init commit

This commit is contained in:
flswld
2022-11-20 15:38:00 +08:00
parent eda2b643b9
commit 3efed3defe
5834 changed files with 636508 additions and 0 deletions

View File

@@ -0,0 +1,89 @@
package service
import "air/entity"
// 获取HTTP服务
func (s *Service) FetchHttpService(name string) (r []entity.Instance) {
s.httpServiceMapLock.RLock()
instanceMap := s.httpServiceMap[name]
s.httpServiceMapLock.RUnlock()
r = make([]entity.Instance, 0)
if instanceMap == nil {
return r
}
instanceMap.lock.RLock()
for k, v := range instanceMap.Imap {
instance := new(entity.Instance)
instance.ServiceName = name
instance.InstanceName = k
instance.InstanceAddr = v.Address
r = append(r, *instance)
}
instanceMap.lock.RUnlock()
return r
}
// 获取所有HTTP服务
func (s *Service) FetchAllHttpService() (r map[string][]entity.Instance) {
s.httpServiceMapLock.RLock()
serviceMap := s.httpServiceMap
s.httpServiceMapLock.RUnlock()
r = make(map[string][]entity.Instance)
for k, v := range serviceMap {
instanceSlice := make([]entity.Instance, 0)
v.lock.RLock()
for kk, vv := range v.Imap {
instance := new(entity.Instance)
instance.ServiceName = k
instance.InstanceName = kk
instance.InstanceAddr = vv.Address
instanceSlice = append(instanceSlice, *instance)
}
v.lock.RUnlock()
r[k] = instanceSlice
}
return r
}
// 获取RPC服务
func (s *Service) FetchRpcService(name string) (r []entity.Instance) {
s.rpcServiceMapLock.RLock()
instanceMap := s.rpcServiceMap[name]
s.rpcServiceMapLock.RUnlock()
r = make([]entity.Instance, 0)
if instanceMap == nil {
return r
}
instanceMap.lock.RLock()
for k, v := range instanceMap.Imap {
instance := new(entity.Instance)
instance.ServiceName = name
instance.InstanceName = k
instance.InstanceAddr = v.Address
r = append(r, *instance)
}
instanceMap.lock.RUnlock()
return r
}
// 获取所有RPC服务
func (s *Service) FetchAllRpcService() (r map[string][]entity.Instance) {
s.rpcServiceMapLock.RLock()
serviceMap := s.rpcServiceMap
s.rpcServiceMapLock.RUnlock()
r = make(map[string][]entity.Instance)
for k, v := range serviceMap {
instanceSlice := make([]entity.Instance, 0)
v.lock.RLock()
for kk, vv := range v.Imap {
instance := new(entity.Instance)
instance.ServiceName = k
instance.InstanceName = kk
instance.InstanceAddr = vv.Address
instanceSlice = append(instanceSlice, *instance)
}
v.lock.RUnlock()
r[k] = instanceSlice
}
return r
}

View File

@@ -0,0 +1,136 @@
package service
import (
"air/entity"
"flswld.com/logger"
"time"
)
// HTTP心跳
func (s *Service) HttpKeepalive(instance entity.Instance) {
nowTime := time.Now().Unix()
s.httpServiceMapLock.RLock()
instanceMap := s.httpServiceMap[instance.ServiceName]
s.httpServiceMapLock.RUnlock()
if instanceMap != nil {
instanceMap.lock.Lock()
instanceData := instanceMap.Imap[instance.InstanceName]
if instanceData != nil {
instanceData.LastAliveTime = nowTime
} else {
logger.LOG.Error("recv not exist instance http keepalive, instance name: %v", instance.InstanceName)
}
instanceMap.lock.Unlock()
} else {
logger.LOG.Error("recv not exist service http keepalive, service name: %v", instance.ServiceName)
}
}
// RPC心跳
func (s *Service) RpcKeepalive(instance entity.Instance) {
nowTime := time.Now().Unix()
s.rpcServiceMapLock.RLock()
instanceMap := s.rpcServiceMap[instance.ServiceName]
s.rpcServiceMapLock.RUnlock()
if instanceMap != nil {
instanceMap.lock.Lock()
instanceData := instanceMap.Imap[instance.InstanceName]
if instanceData != nil {
instanceData.LastAliveTime = nowTime
} else {
logger.LOG.Error("recv not exist instance rpc keepalive, instance name: %v", instance.InstanceName)
}
instanceMap.lock.Unlock()
} else {
logger.LOG.Error("recv not exist service rpc keepalive, service name: %v", instance.ServiceName)
}
}
// 定时移除掉线服务
func (s *Service) removeDeadService() {
ticker := time.NewTicker(time.Second * 60)
for {
<-ticker.C
nowTime := time.Now().Unix()
httpSvcChgFlagMap := make(map[string]bool)
httpSvcChgMap := make(map[string]*InstanceMap)
httpSvcDelMap := make(map[string]*InstanceMap)
s.httpServiceMapLock.RLock()
for svcName, svcInstMap := range s.httpServiceMap {
svcInstMap.lock.Lock()
for instName, instData := range svcInstMap.Imap {
if nowTime-instData.LastAliveTime > 60 {
httpSvcChgFlagMap[svcName] = true
if httpSvcDelMap[svcName] == nil {
httpSvcDelMap[svcName] = new(InstanceMap)
httpSvcDelMap[svcName].Imap = make(map[string]*InstanceData)
}
httpSvcDelMap[svcName].Imap[instName] = instData
delete(svcInstMap.Imap, instName)
} else {
if httpSvcChgMap[svcName] == nil {
httpSvcChgMap[svcName] = new(InstanceMap)
httpSvcChgMap[svcName].Imap = make(map[string]*InstanceData)
}
httpSvcChgMap[svcName].Imap[instName] = instData
}
}
svcInstMap.lock.Unlock()
}
s.httpServiceMapLock.RUnlock()
for svcName, instMap := range httpSvcDelMap {
for instName, instData := range instMap.Imap {
logger.LOG.Info("remove timeout http service, service name: %v, instance name: %v, instance data: %v", svcName, instName, instData)
}
}
for svcName, _ := range httpSvcChgMap {
if !httpSvcChgFlagMap[svcName] {
delete(httpSvcChgMap, svcName)
}
}
if len(httpSvcChgMap) != 0 {
s.httpSvcChgNtfCh <- httpSvcChgMap
}
rpcSvcChgFlagMap := make(map[string]bool)
rpcSvcChgMap := make(map[string]*InstanceMap)
rpcSvcDelMap := make(map[string]*InstanceMap)
s.rpcServiceMapLock.RLock()
for svcName, svcInstMap := range s.rpcServiceMap {
svcInstMap.lock.Lock()
for instName, instData := range svcInstMap.Imap {
if nowTime-instData.LastAliveTime > 60 {
rpcSvcChgFlagMap[svcName] = true
if rpcSvcDelMap[svcName] == nil {
rpcSvcDelMap[svcName] = new(InstanceMap)
rpcSvcDelMap[svcName].Imap = make(map[string]*InstanceData)
}
rpcSvcDelMap[svcName].Imap[instName] = instData
delete(svcInstMap.Imap, instName)
} else {
if rpcSvcChgMap[svcName] == nil {
rpcSvcChgMap[svcName] = new(InstanceMap)
rpcSvcChgMap[svcName].Imap = make(map[string]*InstanceData)
}
rpcSvcChgMap[svcName].Imap[instName] = instData
}
}
svcInstMap.lock.Unlock()
}
s.rpcServiceMapLock.RUnlock()
for svcName, instMap := range rpcSvcDelMap {
for instName, instData := range instMap.Imap {
logger.LOG.Info("remove timeout rpc service, service name: %v, instance name: %v, instance data: %v", svcName, instName, instData)
}
}
for svcName, _ := range rpcSvcChgMap {
if !rpcSvcChgFlagMap[svcName] {
delete(rpcSvcChgMap, svcName)
}
}
if len(rpcSvcChgMap) != 0 {
s.rpcSvcChgNtfCh <- rpcSvcChgMap
}
}
}

190
air/service/poll_service.go Normal file
View File

@@ -0,0 +1,190 @@
package service
import (
"air/entity"
"flswld.com/logger"
"sync/atomic"
"time"
)
func (s *Service) watchServiceChange() {
s.watcher.receiverNotifierIdCounter = 0
s.watcher.httpRecvrNtfrMap = make(map[string]map[uint64]*ReceiverNotifier)
s.watcher.httpAllSvcRecvrNtfrMap = make(map[uint64]*AllServiceReceiverNotifier)
s.watcher.rpcRecvrNtfrMap = make(map[string]map[uint64]*ReceiverNotifier)
s.watcher.rpcAllSvcRecvrNtfrMap = make(map[uint64]*AllServiceReceiverNotifier)
go func() {
for {
imap := <-s.httpSvcChgNtfCh
for svcName, instMap := range imap {
// 给某个服务的接收者通知器发送消息
s.watcher.httpRecvrNtfrMapLock.RLock()
recvrNtfrMap := s.watcher.httpRecvrNtfrMap[svcName]
instList := make([]entity.Instance, 0)
for instName, instData := range instMap.Imap {
inst := new(entity.Instance)
inst.ServiceName = svcName
inst.InstanceName = instName
inst.InstanceAddr = instData.Address
instList = append(instList, *inst)
}
if recvrNtfrMap == nil || len(recvrNtfrMap) == 0 {
s.watcher.httpRecvrNtfrMapLock.RUnlock()
continue
}
for _, recvrNtfr := range recvrNtfrMap {
if time.Now().UnixNano()-recvrNtfr.CreateTime < int64(time.Second*30) {
logger.LOG.Debug("send http service change notify to receiver: %d", recvrNtfr.Id)
recvrNtfr.NotifyChannel <- instList
}
close(recvrNtfr.NotifyChannel)
}
s.watcher.httpRecvrNtfrMapLock.RUnlock()
}
// 给全体服务的接收者通知器发送消息
s.watcher.httpAllSvcRecvrNtfrMapLock.RLock()
if len(s.watcher.httpAllSvcRecvrNtfrMap) == 0 {
s.watcher.httpAllSvcRecvrNtfrMapLock.RUnlock()
continue
}
svcMap := s.FetchAllHttpService()
for _, recvrNtfr := range s.watcher.httpAllSvcRecvrNtfrMap {
if time.Now().UnixNano()-recvrNtfr.CreateTime < int64(time.Second*30) {
logger.LOG.Debug("send all http service change notify to receiver: %d", recvrNtfr.Id)
recvrNtfr.NotifyChannel <- svcMap
}
close(recvrNtfr.NotifyChannel)
}
s.watcher.httpAllSvcRecvrNtfrMapLock.RUnlock()
}
}()
go func() {
for {
imap := <-s.rpcSvcChgNtfCh
for svcName, instMap := range imap {
// 给某个服务的接收者通知器发送消息
s.watcher.rpcRecvrNtfrMapLock.RLock()
recvrNtfrMap := s.watcher.rpcRecvrNtfrMap[svcName]
instList := make([]entity.Instance, 0)
for instName, instData := range instMap.Imap {
inst := new(entity.Instance)
inst.ServiceName = svcName
inst.InstanceName = instName
inst.InstanceAddr = instData.Address
instList = append(instList, *inst)
}
if recvrNtfrMap == nil || len(recvrNtfrMap) == 0 {
s.watcher.rpcRecvrNtfrMapLock.RUnlock()
continue
}
for _, recvrNtfr := range recvrNtfrMap {
if time.Now().UnixNano()-recvrNtfr.CreateTime < int64(time.Second*30) {
logger.LOG.Debug("send rpc service change notify to receiver: %d", recvrNtfr.Id)
recvrNtfr.NotifyChannel <- instList
}
close(recvrNtfr.NotifyChannel)
}
s.watcher.rpcRecvrNtfrMapLock.RUnlock()
}
// 给全体服务的接收者通知器发送消息
s.watcher.rpcAllSvcRecvrNtfrMapLock.RLock()
if len(s.watcher.rpcAllSvcRecvrNtfrMap) == 0 {
s.watcher.rpcAllSvcRecvrNtfrMapLock.RUnlock()
continue
}
svcMap := s.FetchAllRpcService()
for _, recvrNtfr := range s.watcher.rpcAllSvcRecvrNtfrMap {
if time.Now().UnixNano()-recvrNtfr.CreateTime < int64(time.Second*30) {
logger.LOG.Debug("send all rpc service change notify to receiver: %d", recvrNtfr.Id)
recvrNtfr.NotifyChannel <- svcMap
}
close(recvrNtfr.NotifyChannel)
}
s.watcher.rpcAllSvcRecvrNtfrMapLock.RUnlock()
}
}()
}
// 注册HTTP服务变化通知接收者
func (s *Service) RegistryHttpNotifyReceiver(serviceName string) *ReceiverNotifier {
recvrNtfr := new(ReceiverNotifier)
recvrNtfr.Id = atomic.AddUint64(&s.watcher.receiverNotifierIdCounter, 1)
recvrNtfr.CreateTime = time.Now().UnixNano()
recvrNtfr.NotifyChannel = make(chan []entity.Instance, 0)
s.watcher.httpRecvrNtfrMapLock.Lock()
if s.watcher.httpRecvrNtfrMap[serviceName] == nil {
s.watcher.httpRecvrNtfrMap[serviceName] = make(map[uint64]*ReceiverNotifier)
}
s.watcher.httpRecvrNtfrMap[serviceName][recvrNtfr.Id] = recvrNtfr
s.watcher.httpRecvrNtfrMapLock.Unlock()
return recvrNtfr
}
// 取消HTTP服务变化通知接收者
func (s *Service) CancelHttpNotifyReceiver(serviceName string, id uint64) {
s.watcher.httpRecvrNtfrMapLock.Lock()
delete(s.watcher.httpRecvrNtfrMap[serviceName], id)
s.watcher.httpRecvrNtfrMapLock.Unlock()
}
// 注册全体HTTP服务变化通知接收者
func (s *Service) RegistryAllHttpNotifyReceiver() *AllServiceReceiverNotifier {
recvrNtfr := new(AllServiceReceiverNotifier)
recvrNtfr.Id = atomic.AddUint64(&s.watcher.receiverNotifierIdCounter, 1)
recvrNtfr.CreateTime = time.Now().UnixNano()
recvrNtfr.NotifyChannel = make(chan map[string][]entity.Instance, 0)
s.watcher.httpAllSvcRecvrNtfrMapLock.Lock()
s.watcher.httpAllSvcRecvrNtfrMap[recvrNtfr.Id] = recvrNtfr
s.watcher.httpAllSvcRecvrNtfrMapLock.Unlock()
return recvrNtfr
}
// 取消全体HTTP服务变化通知接收者
func (s *Service) CancelAllHttpNotifyReceiver(id uint64) {
s.watcher.httpAllSvcRecvrNtfrMapLock.Lock()
delete(s.watcher.httpAllSvcRecvrNtfrMap, id)
s.watcher.httpAllSvcRecvrNtfrMapLock.Unlock()
}
// 注册RPC服务变化通知接收者
func (s *Service) RegistryRpcNotifyReceiver(serviceName string) *ReceiverNotifier {
recvrNtfr := new(ReceiverNotifier)
recvrNtfr.Id = atomic.AddUint64(&s.watcher.receiverNotifierIdCounter, 1)
recvrNtfr.CreateTime = time.Now().UnixNano()
recvrNtfr.NotifyChannel = make(chan []entity.Instance, 0)
s.watcher.rpcRecvrNtfrMapLock.Lock()
if s.watcher.rpcRecvrNtfrMap[serviceName] == nil {
s.watcher.rpcRecvrNtfrMap[serviceName] = make(map[uint64]*ReceiverNotifier)
}
s.watcher.rpcRecvrNtfrMap[serviceName][recvrNtfr.Id] = recvrNtfr
s.watcher.rpcRecvrNtfrMapLock.Unlock()
return recvrNtfr
}
// 取消RPC服务变化通知接收者
func (s *Service) CancelRpcNotifyReceiver(serviceName string, id uint64) {
s.watcher.rpcRecvrNtfrMapLock.Lock()
delete(s.watcher.rpcRecvrNtfrMap[serviceName], id)
s.watcher.rpcRecvrNtfrMapLock.Unlock()
}
// 注册全体RPC服务变化通知接收者
func (s *Service) RegistryAllRpcNotifyReceiver() *AllServiceReceiverNotifier {
recvrNtfr := new(AllServiceReceiverNotifier)
recvrNtfr.Id = atomic.AddUint64(&s.watcher.receiverNotifierIdCounter, 1)
recvrNtfr.CreateTime = time.Now().UnixNano()
recvrNtfr.NotifyChannel = make(chan map[string][]entity.Instance, 0)
s.watcher.rpcAllSvcRecvrNtfrMapLock.Lock()
s.watcher.rpcAllSvcRecvrNtfrMap[recvrNtfr.Id] = recvrNtfr
s.watcher.rpcAllSvcRecvrNtfrMapLock.Unlock()
return recvrNtfr
}
// 取消全体RPC服务变化通知接收者
func (s *Service) CancelAllRpcNotifyReceiver(id uint64) {
s.watcher.rpcAllSvcRecvrNtfrMapLock.Lock()
delete(s.watcher.rpcAllSvcRecvrNtfrMap, id)
s.watcher.rpcAllSvcRecvrNtfrMapLock.Unlock()
}

View File

@@ -0,0 +1,103 @@
package service
import (
"air/entity"
"flswld.com/common/utils/object"
"time"
)
// 注册HTTP服务
func (s *Service) RegisterHttpService(instance entity.Instance) bool {
nowTime := time.Now().Unix()
s.httpServiceMapLock.Lock()
instanceMap := s.httpServiceMap[instance.ServiceName]
if instanceMap == nil {
instanceMap = new(InstanceMap)
instanceMap.Imap = make(map[string]*InstanceData)
}
instanceMap.lock.Lock()
instanceData := instanceMap.Imap[instance.InstanceName]
if instanceData == nil {
instanceData = new(InstanceData)
}
instanceData.Address = instance.InstanceAddr
instanceData.LastAliveTime = nowTime
instanceMap.Imap[instance.InstanceName] = instanceData
s.httpServiceMap[instance.ServiceName] = instanceMap
instanceMap.lock.Unlock()
s.httpServiceMapLock.Unlock()
changeInst := make(map[string]*InstanceMap)
instanceMapCopy := new(InstanceMap)
instanceMap.lock.RLock()
_ = object.ObjectDeepCopy(instanceMap, instanceMapCopy)
instanceMap.lock.RUnlock()
changeInst[instance.ServiceName] = instanceMapCopy
s.httpSvcChgNtfCh <- changeInst
return true
}
// 取消注册HTTP服务
func (s *Service) CancelHttpService(instance entity.Instance) bool {
s.httpServiceMapLock.RLock()
instanceMap := s.httpServiceMap[instance.ServiceName]
s.httpServiceMapLock.RUnlock()
instanceMap.lock.Lock()
delete(instanceMap.Imap, instance.InstanceName)
instanceMap.lock.Unlock()
changeInst := make(map[string]*InstanceMap)
instanceMapCopy := new(InstanceMap)
instanceMap.lock.RLock()
_ = object.ObjectDeepCopy(instanceMap, instanceMapCopy)
instanceMap.lock.RUnlock()
changeInst[instance.ServiceName] = instanceMapCopy
s.httpSvcChgNtfCh <- changeInst
return true
}
// 注册RPC服务
func (s *Service) RegisterRpcService(instance entity.Instance) bool {
nowTime := time.Now().Unix()
s.rpcServiceMapLock.Lock()
instanceMap := s.rpcServiceMap[instance.ServiceName]
if instanceMap == nil {
instanceMap = new(InstanceMap)
instanceMap.Imap = make(map[string]*InstanceData)
}
instanceMap.lock.Lock()
instanceData := instanceMap.Imap[instance.InstanceName]
if instanceData == nil {
instanceData = new(InstanceData)
}
instanceData.Address = instance.InstanceAddr
instanceData.LastAliveTime = nowTime
instanceMap.Imap[instance.InstanceName] = instanceData
s.rpcServiceMap[instance.ServiceName] = instanceMap
instanceMap.lock.Unlock()
s.rpcServiceMapLock.Unlock()
changeInst := make(map[string]*InstanceMap)
instanceMapCopy := new(InstanceMap)
instanceMap.lock.RLock()
_ = object.ObjectDeepCopy(instanceMap, instanceMapCopy)
instanceMap.lock.RUnlock()
changeInst[instance.ServiceName] = instanceMapCopy
s.rpcSvcChgNtfCh <- changeInst
return true
}
// 取消注册RPC服务
func (s *Service) CancelRpcService(instance entity.Instance) bool {
s.rpcServiceMapLock.RLock()
instanceMap := s.rpcServiceMap[instance.ServiceName]
s.rpcServiceMapLock.RUnlock()
instanceMap.lock.Lock()
delete(instanceMap.Imap, instance.InstanceName)
instanceMap.lock.Unlock()
changeInst := make(map[string]*InstanceMap)
instanceMapCopy := new(InstanceMap)
instanceMap.lock.RLock()
_ = object.ObjectDeepCopy(instanceMap, instanceMapCopy)
instanceMap.lock.RUnlock()
changeInst[instance.ServiceName] = instanceMapCopy
s.rpcSvcChgNtfCh <- changeInst
return true
}

75
air/service/service.go Normal file
View File

@@ -0,0 +1,75 @@
package service
import (
"air/entity"
"sync"
)
// 实例数据
type InstanceData struct {
// 实例地址
Address string
// 最后心跳时间
LastAliveTime int64
}
// 服务实例集合
type InstanceMap struct {
// key:实例名 value:实例数据
Imap map[string]*InstanceData
lock sync.RWMutex
}
type ReceiverNotifier struct {
Id uint64
CreateTime int64
NotifyChannel chan []entity.Instance
}
type AllServiceReceiverNotifier struct {
Id uint64
CreateTime int64
NotifyChannel chan map[string][]entity.Instance
}
type Watcher struct {
receiverNotifierIdCounter uint64
// key1:服务名 key2:接收者通知器id value:接收者通知器
httpRecvrNtfrMap map[string]map[uint64]*ReceiverNotifier
httpRecvrNtfrMapLock sync.RWMutex
// key:接收者通知器id value:接收者通知器
httpAllSvcRecvrNtfrMap map[uint64]*AllServiceReceiverNotifier
httpAllSvcRecvrNtfrMapLock sync.RWMutex
// key1:服务名 key2:接收者通知器id value:接收者通知器
rpcRecvrNtfrMap map[string]map[uint64]*ReceiverNotifier
rpcRecvrNtfrMapLock sync.RWMutex
// key:接收者通知器id value:接收者通知器
rpcAllSvcRecvrNtfrMap map[uint64]*AllServiceReceiverNotifier
rpcAllSvcRecvrNtfrMapLock sync.RWMutex
}
// 注册服务
type Service struct {
// key:服务名 value:服务实例集合
httpServiceMap map[string]*InstanceMap
httpServiceMapLock sync.RWMutex
httpSvcChgNtfCh chan map[string]*InstanceMap
// key:服务名 value:服务实例集合
rpcServiceMap map[string]*InstanceMap
rpcServiceMapLock sync.RWMutex
rpcSvcChgNtfCh chan map[string]*InstanceMap
watcher *Watcher
}
// 构造函数
func NewService() (r *Service) {
r = new(Service)
r.httpServiceMap = make(map[string]*InstanceMap)
r.rpcServiceMap = make(map[string]*InstanceMap)
r.httpSvcChgNtfCh = make(chan map[string]*InstanceMap, 0)
r.rpcSvcChgNtfCh = make(chan map[string]*InstanceMap, 0)
r.watcher = new(Watcher)
go r.removeDeadService()
go r.watchServiceChange()
return r
}