mirror of
https://github.com/duanhf2012/origin.git
synced 2026-02-24 06:34:42 +08:00
新增etcd服务发现
This commit is contained in:
@@ -20,23 +20,25 @@ const (
|
|||||||
Discard NodeStatus = 1 //丢弃
|
Discard NodeStatus = 1 //丢弃
|
||||||
)
|
)
|
||||||
|
|
||||||
type MasterDiscoveryService struct {
|
type DiscoveryService struct {
|
||||||
MasterNodeId string //要筛选的主结点Id,如果不配置或者配置成0,表示针对所有的主结点
|
MasterNodeId string //要筛选的主结点Id,如果不配置或者配置成0,表示针对所有的主结点
|
||||||
DiscoveryService []string //只发现的服务列表
|
NetworkName string //如果是etcd,指定要筛选的网络名中的服务,不配置,表示所有的网络
|
||||||
|
ServiceList []string //只发现的服务列表
|
||||||
}
|
}
|
||||||
|
|
||||||
type NodeInfo struct {
|
type NodeInfo struct {
|
||||||
NodeId string
|
NodeId string
|
||||||
//NodeName string
|
|
||||||
Private bool
|
Private bool
|
||||||
ListenAddr string
|
ListenAddr string
|
||||||
MaxRpcParamLen uint32 //最大Rpc参数长度
|
MaxRpcParamLen uint32 //最大Rpc参数长度
|
||||||
CompressBytesLen int //超过字节进行压缩的长度
|
CompressBytesLen int //超过字节进行压缩的长度
|
||||||
ServiceList []string //所有的有序服务列表
|
ServiceList []string //所有的有序服务列表
|
||||||
PublicServiceList []string //对外公开的服务列表
|
PublicServiceList []string //对外公开的服务列表
|
||||||
MasterDiscoveryService []MasterDiscoveryService //筛选发现的服务,如果不配置,不进行筛选
|
DiscoveryService []DiscoveryService //筛选发现的服务,如果不配置,不进行筛选
|
||||||
status NodeStatus
|
status NodeStatus
|
||||||
Retire bool
|
Retire bool
|
||||||
|
|
||||||
|
NetworkName string
|
||||||
}
|
}
|
||||||
|
|
||||||
type NodeRpcInfo struct {
|
type NodeRpcInfo struct {
|
||||||
@@ -48,7 +50,9 @@ var cluster Cluster
|
|||||||
|
|
||||||
type Cluster struct {
|
type Cluster struct {
|
||||||
localNodeInfo NodeInfo //本结点配置信息
|
localNodeInfo NodeInfo //本结点配置信息
|
||||||
masterDiscoveryNodeList []NodeInfo //配置发现Master结点
|
|
||||||
|
discoveryInfo DiscoveryInfo //服务发现配置
|
||||||
|
//masterDiscoveryNodeList []NodeInfo //配置发现Master结点
|
||||||
globalCfg interface{} //全局配置
|
globalCfg interface{} //全局配置
|
||||||
|
|
||||||
localServiceCfg map[string]interface{} //map[serviceName]配置数据*
|
localServiceCfg map[string]interface{} //map[serviceName]配置数据*
|
||||||
@@ -83,7 +87,6 @@ func (cls *Cluster) Start() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cls *Cluster) Stop() {
|
func (cls *Cluster) Stop() {
|
||||||
cls.serviceDiscovery.OnNodeStop()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cls *Cluster) DiscardNode(nodeId string) {
|
func (cls *Cluster) DiscardNode(nodeId string) {
|
||||||
@@ -99,7 +102,7 @@ func (cls *Cluster) DiscardNode(nodeId string) {
|
|||||||
|
|
||||||
func (cls *Cluster) DelNode(nodeId string, immediately bool) {
|
func (cls *Cluster) DelNode(nodeId string, immediately bool) {
|
||||||
//MasterDiscover结点与本地结点不删除
|
//MasterDiscover结点与本地结点不删除
|
||||||
if cls.GetMasterDiscoveryNodeInfo(nodeId) != nil || nodeId == cls.localNodeInfo.NodeId {
|
if cls.IsOriginMasterDiscoveryNode(nodeId) || nodeId == cls.localNodeInfo.NodeId {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cls.locker.Lock()
|
cls.locker.Lock()
|
||||||
@@ -132,10 +135,6 @@ func (cls *Cluster) DelNode(nodeId string, immediately bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cls *Cluster) serviceDiscoveryDelNode(nodeId string, immediately bool) {
|
func (cls *Cluster) serviceDiscoveryDelNode(nodeId string, immediately bool) {
|
||||||
//if nodeId == "" {
|
|
||||||
// return
|
|
||||||
//}
|
|
||||||
|
|
||||||
cls.DelNode(nodeId, immediately)
|
cls.DelNode(nodeId, immediately)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +197,6 @@ func (cls *Cluster) serviceDiscoverySetNodeInfo(nodeInfo *NodeInfo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func (cls *Cluster) Init(localNodeId string, setupServiceFun SetupServiceFun) error {
|
func (cls *Cluster) Init(localNodeId string, setupServiceFun SetupServiceFun) error {
|
||||||
//1.初始化配置
|
//1.初始化配置
|
||||||
err := cls.InitCfg(localNodeId)
|
err := cls.InitCfg(localNodeId)
|
||||||
@@ -209,7 +207,11 @@ func (cls *Cluster) Init(localNodeId string, setupServiceFun SetupServiceFun) er
|
|||||||
cls.rpcServer.Init(cls)
|
cls.rpcServer.Init(cls)
|
||||||
|
|
||||||
//2.安装服务发现结点
|
//2.安装服务发现结点
|
||||||
cls.SetupServiceDiscovery(localNodeId, setupServiceFun)
|
err = cls.setupDiscovery(localNodeId, setupServiceFun)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("setupDiscovery fail",log.ErrorAttr("err",err))
|
||||||
|
return err
|
||||||
|
}
|
||||||
service.RegRpcEventFun = cls.RegRpcEvent
|
service.RegRpcEventFun = cls.RegRpcEvent
|
||||||
service.UnRegRpcEventFun = cls.UnRegRpcEvent
|
service.UnRegRpcEventFun = cls.UnRegRpcEvent
|
||||||
service.RegDiscoveryServiceEventFun = cls.RegDiscoveryEvent
|
service.RegDiscoveryServiceEventFun = cls.RegDiscoveryEvent
|
||||||
@@ -223,73 +225,6 @@ func (cls *Cluster) Init(localNodeId string, setupServiceFun SetupServiceFun) er
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cls *Cluster) checkDynamicDiscovery(localNodeId string) (bool, bool) {
|
|
||||||
var localMaster bool //本结点是否为Master结点
|
|
||||||
var hasMaster bool //是否配置Master服务
|
|
||||||
|
|
||||||
//遍历所有结点
|
|
||||||
for _, nodeInfo := range cls.masterDiscoveryNodeList {
|
|
||||||
if nodeInfo.NodeId == localNodeId {
|
|
||||||
localMaster = true
|
|
||||||
}
|
|
||||||
hasMaster = true
|
|
||||||
}
|
|
||||||
|
|
||||||
//返回查询结果
|
|
||||||
return localMaster, hasMaster
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cls *Cluster) AddDynamicDiscoveryService(serviceName string, bPublicService bool) {
|
|
||||||
addServiceList := append([]string{},serviceName)
|
|
||||||
cls.localNodeInfo.ServiceList = append(addServiceList,cls.localNodeInfo.ServiceList...)
|
|
||||||
if bPublicService {
|
|
||||||
cls.localNodeInfo.PublicServiceList = append(cls.localNodeInfo.PublicServiceList, serviceName)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := cls.mapServiceNode[serviceName]; ok == false {
|
|
||||||
cls.mapServiceNode[serviceName] = map[string]struct{}{}
|
|
||||||
}
|
|
||||||
cls.mapServiceNode[serviceName][cls.localNodeInfo.NodeId] = struct{}{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cls *Cluster) GetDiscoveryNodeList() []NodeInfo {
|
|
||||||
return cls.masterDiscoveryNodeList
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cls *Cluster) GetMasterDiscoveryNodeInfo(nodeId string) *NodeInfo {
|
|
||||||
for i := 0; i < len(cls.masterDiscoveryNodeList); i++ {
|
|
||||||
if cls.masterDiscoveryNodeList[i].NodeId == nodeId {
|
|
||||||
return &cls.masterDiscoveryNodeList[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cls *Cluster) IsMasterDiscoveryNode() bool {
|
|
||||||
return cls.GetMasterDiscoveryNodeInfo(cls.GetLocalNodeInfo().NodeId) != nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cls *Cluster) SetupServiceDiscovery(localNodeId string, setupServiceFun SetupServiceFun) {
|
|
||||||
if cls.serviceDiscovery != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//1.如果没有配置DiscoveryNode配置,则使用默认配置文件发现服务
|
|
||||||
localMaster, hasMaster := cls.checkDynamicDiscovery(localNodeId)
|
|
||||||
if hasMaster == false {
|
|
||||||
cls.serviceDiscovery = &ConfigDiscovery{}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
setupServiceFun(&masterService, &clientService)
|
|
||||||
|
|
||||||
//2.如果为动态服务发现安装本地发现服务
|
|
||||||
cls.serviceDiscovery = getDynamicDiscovery()
|
|
||||||
cls.AddDynamicDiscoveryService(DynamicDiscoveryClientName, true)
|
|
||||||
if localMaster == true {
|
|
||||||
cls.AddDynamicDiscoveryService(DynamicDiscoveryMasterName, false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cls *Cluster) FindRpcHandler(serviceName string) rpc.IRpcHandler {
|
func (cls *Cluster) FindRpcHandler(serviceName string) rpc.IRpcHandler {
|
||||||
pService := service.GetService(serviceName)
|
pService := service.GetService(serviceName)
|
||||||
@@ -488,3 +423,26 @@ func (cls *Cluster) GetNodeInfo(nodeId string) (NodeInfo,bool) {
|
|||||||
|
|
||||||
return nodeInfo.nodeInfo,true
|
return nodeInfo.nodeInfo,true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (dc *Cluster) CanDiscoveryService(fromMasterNodeId string,serviceName string) bool{
|
||||||
|
canDiscovery := true
|
||||||
|
|
||||||
|
for i:=0;i<len(dc.GetLocalNodeInfo().DiscoveryService);i++{
|
||||||
|
masterNodeId := dc.GetLocalNodeInfo().DiscoveryService[i].MasterNodeId
|
||||||
|
//无效的配置,则跳过
|
||||||
|
if masterNodeId == rpc.NodeIdNull && len(dc.GetLocalNodeInfo().DiscoveryService[i].ServiceList)==0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
canDiscovery = false
|
||||||
|
if masterNodeId == fromMasterNodeId || masterNodeId == rpc.NodeIdNull {
|
||||||
|
for _,discoveryService := range dc.GetLocalNodeInfo().DiscoveryService[i].ServiceList {
|
||||||
|
if discoveryService == serviceName {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return canDiscovery
|
||||||
|
}
|
||||||
@@ -3,17 +3,17 @@ package cluster
|
|||||||
import "github.com/duanhf2012/origin/v2/rpc"
|
import "github.com/duanhf2012/origin/v2/rpc"
|
||||||
|
|
||||||
type ConfigDiscovery struct {
|
type ConfigDiscovery struct {
|
||||||
funDelService FunDelNode
|
funDelNode FunDelNode
|
||||||
funSetService FunSetNodeInfo
|
funSetNode FunSetNode
|
||||||
localNodeId string
|
localNodeId string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (discovery *ConfigDiscovery) InitDiscovery(localNodeId string,funDelNode FunDelNode,funSetNodeInfo FunSetNodeInfo) error{
|
func (discovery *ConfigDiscovery) InitDiscovery(localNodeId string,funDelNode FunDelNode,funSetNode FunSetNode) error{
|
||||||
discovery.localNodeId = localNodeId
|
discovery.localNodeId = localNodeId
|
||||||
discovery.funDelService = funDelNode
|
discovery.funDelNode = funDelNode
|
||||||
discovery.funSetService = funSetNodeInfo
|
discovery.funSetNode = funSetNode
|
||||||
|
|
||||||
//解析本地其他服务配置
|
//解析本地其他服务配置
|
||||||
_,nodeInfoList,err := GetCluster().readLocalClusterConfig(rpc.NodeIdNull)
|
_,nodeInfoList,err := GetCluster().readLocalClusterConfig(rpc.NodeIdNull)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -25,12 +25,10 @@ func (discovery *ConfigDiscovery) InitDiscovery(localNodeId string,funDelNode Fu
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
discovery.funSetService(&nodeInfo)
|
discovery.funSetNode(&nodeInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (discovery *ConfigDiscovery) OnNodeStop(){
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
71
cluster/discovery.go
Normal file
71
cluster/discovery.go
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
package cluster
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/duanhf2012/origin/v2/service"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (cls *Cluster) setupDiscovery(localNodeId string, setupServiceFun SetupServiceFun) error{
|
||||||
|
if cls.discoveryInfo.getDiscoveryType() == OriginType { //origin类型服务发现
|
||||||
|
return cls.setupOriginDiscovery(localNodeId,setupServiceFun)
|
||||||
|
}else if cls.discoveryInfo.getDiscoveryType() == EtcdType{//etcd类型服务发现
|
||||||
|
return cls.setupEtcdDiscovery(localNodeId,setupServiceFun)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cls.setupConfigDiscovery(localNodeId,setupServiceFun)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cls *Cluster) setupOriginDiscovery(localNodeId string, setupServiceFun SetupServiceFun) error{
|
||||||
|
if cls.serviceDiscovery != nil {
|
||||||
|
return errors.New("service discovery has been setup")
|
||||||
|
}
|
||||||
|
|
||||||
|
//1.如果没有配置DiscoveryNode配置,则使用默认配置文件发现服务
|
||||||
|
localMaster, hasMaster := cls.checkOriginDiscovery(localNodeId)
|
||||||
|
if hasMaster == false {
|
||||||
|
return errors.New("no master node config")
|
||||||
|
}
|
||||||
|
|
||||||
|
cls.serviceDiscovery = getOriginDiscovery()
|
||||||
|
//2.如果为动态服务发现安装本地发现服务
|
||||||
|
if localMaster == true {
|
||||||
|
setupServiceFun(&masterService)
|
||||||
|
cls.AddDiscoveryService(OriginDiscoveryMasterName, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
setupServiceFun(&clientService)
|
||||||
|
cls.AddDiscoveryService(OriginDiscoveryClientName, true)
|
||||||
|
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cls *Cluster) setupEtcdDiscovery(localNodeId string, setupServiceFun SetupServiceFun) error{
|
||||||
|
if cls.serviceDiscovery != nil {
|
||||||
|
return errors.New("service discovery has been setup")
|
||||||
|
}
|
||||||
|
|
||||||
|
//setup etcd service
|
||||||
|
cls.serviceDiscovery = getEtcdDiscovery()
|
||||||
|
setupServiceFun(cls.serviceDiscovery.(service.IService))
|
||||||
|
|
||||||
|
cls.AddDiscoveryService(cls.serviceDiscovery.(service.IService).GetName(),false)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cls *Cluster) setupConfigDiscovery(localNodeId string, setupServiceFun SetupServiceFun) error{
|
||||||
|
if cls.serviceDiscovery != nil {
|
||||||
|
return errors.New("service discovery has been setup")
|
||||||
|
}
|
||||||
|
|
||||||
|
cls.serviceDiscovery = &ConfigDiscovery{}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cls *Cluster) GetOriginDiscoveryNodeList() []NodeInfo {
|
||||||
|
return cls.discoveryInfo.Origin
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cls *Cluster) GetEtcdDiscovery() *EtcdDiscovery {
|
||||||
|
return cls.discoveryInfo.Etcd
|
||||||
|
}
|
||||||
443
cluster/etcddiscovery.go
Normal file
443
cluster/etcddiscovery.go
Normal file
@@ -0,0 +1,443 @@
|
|||||||
|
package cluster
|
||||||
|
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/duanhf2012/origin/v2/event"
|
||||||
|
"github.com/duanhf2012/origin/v2/log"
|
||||||
|
"github.com/duanhf2012/origin/v2/rpc"
|
||||||
|
"github.com/duanhf2012/origin/v2/service"
|
||||||
|
"github.com/duanhf2012/origin/v2/util/timer"
|
||||||
|
"go.etcd.io/etcd/api/v3/mvccpb"
|
||||||
|
"go.etcd.io/etcd/client/v3"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
"sync/atomic"
|
||||||
|
)
|
||||||
|
|
||||||
|
const originDir = "/origin"
|
||||||
|
const testKey = originDir+"/_inner/_test_7501f3ed-b716-44c2-0090-fc1ed0166d7a"
|
||||||
|
|
||||||
|
type etcdClientInfo struct {
|
||||||
|
watchKeys []string
|
||||||
|
leaseID clientv3.LeaseID
|
||||||
|
keepAliveChan <-chan *clientv3.LeaseKeepAliveResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
type EtcdDiscoveryService struct {
|
||||||
|
service.Service
|
||||||
|
funDelNode FunDelNode
|
||||||
|
funSetNode FunSetNode
|
||||||
|
localNodeId string
|
||||||
|
|
||||||
|
byteLocalNodeInfo string
|
||||||
|
mapClient map[*clientv3.Client]*etcdClientInfo
|
||||||
|
isClose int32
|
||||||
|
|
||||||
|
mapDiscoveryNodeId map[string]map[string]struct{} //map[networkName]map[nodeId]
|
||||||
|
}
|
||||||
|
|
||||||
|
func getEtcdDiscovery() (IServiceDiscovery) {
|
||||||
|
etcdDiscovery := &EtcdDiscoveryService{}
|
||||||
|
return etcdDiscovery
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed *EtcdDiscoveryService) InitDiscovery(localNodeId string,funDelNode FunDelNode,funSetNode FunSetNode) error {
|
||||||
|
ed.localNodeId = localNodeId
|
||||||
|
|
||||||
|
ed.funDelNode = funDelNode
|
||||||
|
ed.funSetNode = funSetNode
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const(
|
||||||
|
eeGets = 0
|
||||||
|
eePut = 1
|
||||||
|
eeDelete = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
type etcdDiscoveryEvent struct {
|
||||||
|
typ int
|
||||||
|
watchKey string
|
||||||
|
Kvs []*mvccpb.KeyValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ee *etcdDiscoveryEvent) GetEventType() event.EventType{
|
||||||
|
return event.Sys_Event_EtcdDiscovery
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed *EtcdDiscoveryService) OnInit() error {
|
||||||
|
ed.mapClient = make(map[*clientv3.Client]*etcdClientInfo,1)
|
||||||
|
ed.mapDiscoveryNodeId = make(map[string]map[string]struct{})
|
||||||
|
|
||||||
|
ed.GetEventProcessor().RegEventReceiverFunc(event.Sys_Event_EtcdDiscovery, ed.GetEventHandler(), ed.OnEtcdDiscovery)
|
||||||
|
|
||||||
|
err := ed.marshalNodeInfo()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
etcdDiscoveryCfg := cluster.GetEtcdDiscovery()
|
||||||
|
if etcdDiscoveryCfg == nil {
|
||||||
|
return errors.New("etcd discovery config is nil.")
|
||||||
|
}
|
||||||
|
|
||||||
|
for i:=0;i<len(etcdDiscoveryCfg.EtcdList);i++{
|
||||||
|
client, cerr := clientv3.New(clientv3.Config{
|
||||||
|
Endpoints: etcdDiscoveryCfg.EtcdList[i].Endpoints,
|
||||||
|
DialTimeout: etcdDiscoveryCfg.DialTimeoutMillisecond,
|
||||||
|
})
|
||||||
|
|
||||||
|
if cerr != nil {
|
||||||
|
log.Error("etcd discovery init fail",log.ErrorAttr("err",cerr))
|
||||||
|
return cerr
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx,_:=context.WithTimeout(context.Background(),time.Second*3)
|
||||||
|
_,err = client.Put(ctx,testKey,"")
|
||||||
|
if err != nil {
|
||||||
|
log.Error("etcd discovery init fail",log.Any("endpoint",etcdDiscoveryCfg.EtcdList[i].Endpoints),log.ErrorAttr("err",err))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ec := &etcdClientInfo{}
|
||||||
|
for _, networkName := range etcdDiscoveryCfg.EtcdList[i].NetworkName {
|
||||||
|
ec.watchKeys = append(ec.watchKeys,fmt.Sprintf("%s/%s",originDir,networkName))
|
||||||
|
//ec.etcdKey = append(ec.etcdKey,fmt.Sprintf("%s/%s/%s",originDir,networkName,nd.localNodeId))
|
||||||
|
}
|
||||||
|
|
||||||
|
ed.mapClient[client] = ec
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed *EtcdDiscoveryService) getRegisterKey(watchkey string) string{
|
||||||
|
return watchkey+"/"+ed.localNodeId
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed *EtcdDiscoveryService) registerServiceByClient(client *clientv3.Client,etcdClient *etcdClientInfo) {
|
||||||
|
// 创建租约
|
||||||
|
var err error
|
||||||
|
var resp *clientv3.LeaseGrantResponse
|
||||||
|
resp, err = client.Grant(context.Background(), cluster.GetEtcdDiscovery().TTLSecond)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("etcd registerService fail",log.ErrorAttr("err",err))
|
||||||
|
ed.tryRegisterService(client,etcdClient)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
etcdClient.leaseID = resp.ID
|
||||||
|
for _,watchKey:= range etcdClient.watchKeys {
|
||||||
|
// 注册服务节点到 etcd
|
||||||
|
_, err = client.Put(context.Background(), ed.getRegisterKey(watchKey), ed.byteLocalNodeInfo, clientv3.WithLease(resp.ID))
|
||||||
|
if err != nil {
|
||||||
|
log.Error("etcd Put fail",log.ErrorAttr("err",err))
|
||||||
|
ed.tryRegisterService(client,etcdClient)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
etcdClient.keepAliveChan,err = client.KeepAlive(context.Background(), etcdClient.leaseID)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("etcd KeepAlive fail",log.ErrorAttr("err",err))
|
||||||
|
ed.tryRegisterService(client,etcdClient)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case _, ok := <-etcdClient.keepAliveChan:
|
||||||
|
//log.Debug("ok",log.Any("addr",client.Endpoints()))
|
||||||
|
if !ok {
|
||||||
|
log.Error("etcd keepAliveChan fail",log.Any("watchKeys",etcdClient.watchKeys))
|
||||||
|
ed.tryRegisterService(client,etcdClient)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (ed *EtcdDiscoveryService) tryRegisterService(client *clientv3.Client,etcdClient *etcdClientInfo){
|
||||||
|
if ed.isStop() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ed.AfterFunc(time.Second*3, func(t *timer.Timer) {
|
||||||
|
ed.registerServiceByClient(client,etcdClient)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed *EtcdDiscoveryService) tryWatch(client *clientv3.Client,etcdClient *etcdClientInfo) {
|
||||||
|
if ed.isStop() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ed.AfterFunc(time.Second*3, func(t *timer.Timer) {
|
||||||
|
ed.watchByClient(client,etcdClient)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed *EtcdDiscoveryService) OnRetire(){
|
||||||
|
atomic.StoreInt32(&ed.isClose,1)
|
||||||
|
ed.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed *EtcdDiscoveryService) OnRelease(){
|
||||||
|
atomic.StoreInt32(&ed.isClose,1)
|
||||||
|
ed.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed *EtcdDiscoveryService) isStop() bool{
|
||||||
|
return atomic.LoadInt32(&ed.isClose) == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (nd *EtcdDiscoveryService) OnStart() {
|
||||||
|
for c, ec := range nd.mapClient {
|
||||||
|
nd.tryRegisterService(c,ec)
|
||||||
|
nd.tryWatch(c,ec)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed *EtcdDiscoveryService) marshalNodeInfo() error{
|
||||||
|
nInfo := cluster.GetLocalNodeInfo()
|
||||||
|
var nodeInfo rpc.NodeInfo
|
||||||
|
nodeInfo.NodeId = nInfo.NodeId
|
||||||
|
nodeInfo.ListenAddr = nInfo.ListenAddr
|
||||||
|
nodeInfo.Retire = nInfo.Retire
|
||||||
|
nodeInfo.PublicServiceList = nInfo.PublicServiceList
|
||||||
|
nodeInfo.MaxRpcParamLen = nInfo.MaxRpcParamLen
|
||||||
|
|
||||||
|
byteLocalNodeInfo,err := proto.Marshal(&nodeInfo)
|
||||||
|
if err ==nil{
|
||||||
|
ed.byteLocalNodeInfo = string(byteLocalNodeInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed *EtcdDiscoveryService) setNodeInfo(networkName string,nodeInfo *rpc.NodeInfo) bool{
|
||||||
|
if nodeInfo == nil || nodeInfo.Private == true || nodeInfo.NodeId == ed.localNodeId {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
//筛选关注的服务
|
||||||
|
var discoverServiceSlice = make([]string, 0, 24)
|
||||||
|
for _, pubService := range nodeInfo.PublicServiceList {
|
||||||
|
if cluster.CanDiscoveryService(networkName,pubService) == true {
|
||||||
|
discoverServiceSlice = append(discoverServiceSlice,pubService)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(discoverServiceSlice) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var nInfo NodeInfo
|
||||||
|
nInfo.ServiceList = discoverServiceSlice
|
||||||
|
nInfo.PublicServiceList = discoverServiceSlice
|
||||||
|
nInfo.NodeId = nodeInfo.NodeId
|
||||||
|
nInfo.ListenAddr = nodeInfo.ListenAddr
|
||||||
|
nInfo.MaxRpcParamLen = nodeInfo.MaxRpcParamLen
|
||||||
|
nInfo.Retire = nodeInfo.Retire
|
||||||
|
nInfo.Private = nodeInfo.Private
|
||||||
|
|
||||||
|
ed.funSetNode(&nInfo)
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed *EtcdDiscoveryService) close(){
|
||||||
|
for c, ec := range ed.mapClient {
|
||||||
|
if _, err := c.Revoke(context.Background(), ec.leaseID); err != nil {
|
||||||
|
log.Error("etcd Revoke fail",log.ErrorAttr("err",err))
|
||||||
|
}
|
||||||
|
c.Watcher.Close()
|
||||||
|
err := c.Close()
|
||||||
|
if err != nil {
|
||||||
|
log.Error("etcd Close fail",log.ErrorAttr("err",err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed *EtcdDiscoveryService) getServices(client *clientv3.Client,etcdClient *etcdClientInfo,watchKey string) bool {
|
||||||
|
// 根据前缀获取现有的key
|
||||||
|
resp, err := client.Get(context.Background(), watchKey, clientv3.WithPrefix())
|
||||||
|
if err != nil {
|
||||||
|
log.Error("etcd Get fail", log.ErrorAttr("err", err))
|
||||||
|
ed.tryWatch(client, etcdClient)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 遍历获取得到的k和v
|
||||||
|
ed.notifyGets(watchKey,resp.Kvs)
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed *EtcdDiscoveryService) watchByClient(client *clientv3.Client,etcdClient *etcdClientInfo){
|
||||||
|
//先关闭所有的watcher
|
||||||
|
for _, watchKey := range etcdClient.watchKeys {
|
||||||
|
// 监视前缀,修改变更server
|
||||||
|
go ed.watcher(client,etcdClient, watchKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// watcher 监听Key的前缀
|
||||||
|
func (ed *EtcdDiscoveryService) watcher(client *clientv3.Client,etcdClient *etcdClientInfo,watchKey string) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
buf := make([]byte, 4096)
|
||||||
|
l := runtime.Stack(buf, false)
|
||||||
|
errString := fmt.Sprint(r)
|
||||||
|
log.Dump(string(buf[:l]),log.String("error",errString))
|
||||||
|
|
||||||
|
ed.tryWatch(client,etcdClient)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
log.Debug(">>try watcher")
|
||||||
|
rch := client.Watch(context.Background(), watchKey, clientv3.WithPrefix())
|
||||||
|
|
||||||
|
if ed.getServices(client,etcdClient,watchKey) == false {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for wresp := range rch {
|
||||||
|
for _, ev := range wresp.Events {
|
||||||
|
switch ev.Type {
|
||||||
|
case clientv3.EventTypePut: // 修改或者新增
|
||||||
|
ed.notifyPut(watchKey,ev.Kv)
|
||||||
|
case clientv3.EventTypeDelete: // 删除
|
||||||
|
ed.notifyDelete(watchKey,ev.Kv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ed.tryWatch(client,etcdClient)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed *EtcdDiscoveryService) setNode(netWorkName string,byteNode []byte) string{
|
||||||
|
var nodeInfo rpc.NodeInfo
|
||||||
|
err := proto.Unmarshal(byteNode,&nodeInfo)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Unmarshal fail",log.String("netWorkName",netWorkName),log.ErrorAttr("err",err))
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
ed.setNodeInfo(netWorkName,&nodeInfo)
|
||||||
|
|
||||||
|
return nodeInfo.NodeId
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed *EtcdDiscoveryService) delNode(fullKey string) string{
|
||||||
|
nodeId := ed.getNodeId(fullKey)
|
||||||
|
if nodeId == ed.localNodeId {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
ed.funDelNode(nodeId,true)
|
||||||
|
return nodeId
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed *EtcdDiscoveryService) getNetworkNameByWatchKey(watchKey string) string{
|
||||||
|
return watchKey[strings.LastIndex(watchKey,"/")+1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed *EtcdDiscoveryService) getNetworkNameByFullKey(fullKey string) string{
|
||||||
|
return fullKey[len(originDir)+1:strings.LastIndex(fullKey,"/")]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed *EtcdDiscoveryService) getNodeId(fullKey string) string{
|
||||||
|
return fullKey[strings.LastIndex(fullKey,"/")+1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed *EtcdDiscoveryService) OnEtcdDiscovery(ev event.IEvent){
|
||||||
|
disEvent := ev.(*etcdDiscoveryEvent)
|
||||||
|
switch disEvent.typ {
|
||||||
|
case eeGets:
|
||||||
|
ed.OnEventGets(disEvent.watchKey,disEvent.Kvs)
|
||||||
|
case eePut:
|
||||||
|
if len(disEvent.Kvs) == 1 {
|
||||||
|
ed.OnEventPut(disEvent.watchKey,disEvent.Kvs[0])
|
||||||
|
}
|
||||||
|
case eeDelete:
|
||||||
|
if len(disEvent.Kvs) == 1 {
|
||||||
|
ed.OnEventDelete(disEvent.watchKey,disEvent.Kvs[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed *EtcdDiscoveryService) notifyGets(watchKey string,Kvs []*mvccpb.KeyValue) {
|
||||||
|
var ev etcdDiscoveryEvent
|
||||||
|
ev.typ = eeGets
|
||||||
|
ev.watchKey = watchKey
|
||||||
|
ev.Kvs = Kvs
|
||||||
|
ed.NotifyEvent(&ev)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed *EtcdDiscoveryService) notifyPut(watchKey string,Kvs *mvccpb.KeyValue) {
|
||||||
|
var ev etcdDiscoveryEvent
|
||||||
|
ev.typ = eePut
|
||||||
|
ev.watchKey = watchKey
|
||||||
|
ev.Kvs = append(ev.Kvs,Kvs)
|
||||||
|
ed.NotifyEvent(&ev)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed *EtcdDiscoveryService) notifyDelete(watchKey string,Kvs *mvccpb.KeyValue) {
|
||||||
|
var ev etcdDiscoveryEvent
|
||||||
|
ev.typ = eeDelete
|
||||||
|
ev.watchKey = watchKey
|
||||||
|
ev.Kvs = append(ev.Kvs,Kvs)
|
||||||
|
ed.NotifyEvent(&ev)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed *EtcdDiscoveryService) OnEventGets(watchKey string,Kvs []*mvccpb.KeyValue) {
|
||||||
|
mapNode := make(map[string]struct{},32)
|
||||||
|
for _, kv := range Kvs {
|
||||||
|
nodeId := ed.setNode(ed.getNetworkNameByFullKey(string(kv.Key)), kv.Value)
|
||||||
|
mapNode[nodeId] = struct{}{}
|
||||||
|
ed.addNodeId(watchKey,nodeId)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug(">>etcd OnEventGets",log.String("watchKey",watchKey),log.Any("mapNode",mapNode))
|
||||||
|
// 此段代码为遍历并删除过期节点的逻辑。
|
||||||
|
// 对于mapDiscoveryNodeId中与watchKey关联的所有节点ID,遍历该集合。
|
||||||
|
// 如果某个节点ID不在mapNode中且不是本地节点ID,则调用funDelNode函数删除该节点。
|
||||||
|
mapLastNodeId := ed.mapDiscoveryNodeId[watchKey] // 根据watchKey获取对应的节点ID集合
|
||||||
|
for nodeId := range mapLastNodeId { // 遍历所有节点ID
|
||||||
|
if _,ok := mapNode[nodeId];ok == false && nodeId != ed.localNodeId { // 检查节点是否不存在于mapNode且不是本地节点
|
||||||
|
ed.funDelNode(nodeId,true) // 调用函数删除该节点
|
||||||
|
delete(ed.mapDiscoveryNodeId[watchKey],nodeId)
|
||||||
|
log.Debug(">>etcd OnEventGets Delete",log.String("watchKey",watchKey),log.String("nodeId",nodeId))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed *EtcdDiscoveryService) OnEventPut(watchKey string,Kv *mvccpb.KeyValue) {
|
||||||
|
log.Debug(">>etcd OnEventPut",log.String("watchKey",watchKey),log.String("nodeId",ed.getNodeId(string(Kv.Key))))
|
||||||
|
nodeId := ed.setNode(ed.getNetworkNameByFullKey(string(Kv.Key)), Kv.Value)
|
||||||
|
ed.addNodeId(watchKey,nodeId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed *EtcdDiscoveryService) OnEventDelete(watchKey string,Kv *mvccpb.KeyValue) {
|
||||||
|
log.Debug(">>etcd OnEventDelete",log.String("watchKey",watchKey),log.String("nodeId",ed.getNodeId(string(Kv.Key))))
|
||||||
|
nodeId := ed.delNode(string(Kv.Key))
|
||||||
|
delete(ed.mapDiscoveryNodeId[watchKey],nodeId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed *EtcdDiscoveryService) addNodeId(watchKey string,nodeId string) {
|
||||||
|
if _,ok := ed.mapDiscoveryNodeId[watchKey];ok == false {
|
||||||
|
ed.mapDiscoveryNodeId[watchKey] = make(map[string]struct{})
|
||||||
|
}
|
||||||
|
|
||||||
|
ed.mapDiscoveryNodeId[watchKey][nodeId] = struct{}{}
|
||||||
|
}
|
||||||
@@ -10,49 +10,51 @@ import (
|
|||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
const DynamicDiscoveryMasterName = "DiscoveryMaster"
|
const OriginDiscoveryMasterName = "DiscoveryMaster"
|
||||||
const DynamicDiscoveryClientName = "DiscoveryClient"
|
const OriginDiscoveryClientName = "DiscoveryClient"
|
||||||
const RegServiceDiscover = DynamicDiscoveryMasterName + ".RPC_RegServiceDiscover"
|
const RegServiceDiscover = OriginDiscoveryMasterName + ".RPC_RegServiceDiscover"
|
||||||
const SubServiceDiscover = DynamicDiscoveryClientName + ".RPC_SubServiceDiscover"
|
const SubServiceDiscover = OriginDiscoveryClientName + ".RPC_SubServiceDiscover"
|
||||||
const AddSubServiceDiscover = DynamicDiscoveryMasterName + ".RPC_AddSubServiceDiscover"
|
const AddSubServiceDiscover = OriginDiscoveryMasterName + ".RPC_AddSubServiceDiscover"
|
||||||
const NodeRetireRpcMethod = DynamicDiscoveryMasterName+".RPC_NodeRetire"
|
const NodeRetireRpcMethod = OriginDiscoveryMasterName+".RPC_NodeRetire"
|
||||||
|
|
||||||
type DynamicDiscoveryMaster struct {
|
type OriginDiscoveryMaster struct {
|
||||||
service.Service
|
service.Service
|
||||||
|
|
||||||
mapNodeInfo map[string]struct{}
|
mapNodeInfo map[string]struct{}
|
||||||
nodeInfo []*rpc.NodeInfo
|
nodeInfo []*rpc.NodeInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
type DynamicDiscoveryClient struct {
|
type OriginDiscoveryClient struct {
|
||||||
service.Service
|
service.Service
|
||||||
|
|
||||||
funDelService FunDelNode
|
funDelNode FunDelNode
|
||||||
funSetService FunSetNodeInfo
|
funSetNode FunSetNode
|
||||||
localNodeId string
|
localNodeId string
|
||||||
|
|
||||||
mapDiscovery map[string]map[string]struct{} //map[masterNodeId]map[nodeId]struct{}
|
mapDiscovery map[string]map[string]struct{} //map[masterNodeId]map[nodeId]struct{}
|
||||||
|
mapMasterNetwork map[string]string
|
||||||
bRetire bool
|
bRetire bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var masterService DynamicDiscoveryMaster
|
var masterService OriginDiscoveryMaster
|
||||||
var clientService DynamicDiscoveryClient
|
var clientService OriginDiscoveryClient
|
||||||
|
|
||||||
func getDynamicDiscovery() IServiceDiscovery {
|
func getOriginDiscovery() IServiceDiscovery {
|
||||||
return &clientService
|
return &clientService
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
masterService.SetName(DynamicDiscoveryMasterName)
|
masterService.SetName(OriginDiscoveryMasterName)
|
||||||
clientService.SetName(DynamicDiscoveryClientName)
|
clientService.SetName(OriginDiscoveryClientName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *DynamicDiscoveryMaster) isRegNode(nodeId string) bool {
|
|
||||||
|
func (ds *OriginDiscoveryMaster) isRegNode(nodeId string) bool {
|
||||||
_, ok := ds.mapNodeInfo[nodeId]
|
_, ok := ds.mapNodeInfo[nodeId]
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *DynamicDiscoveryMaster) updateNodeInfo(nInfo *rpc.NodeInfo) {
|
func (ds *OriginDiscoveryMaster) updateNodeInfo(nInfo *rpc.NodeInfo) {
|
||||||
if _,ok:= ds.mapNodeInfo[nInfo.NodeId];ok == false {
|
if _,ok:= ds.mapNodeInfo[nInfo.NodeId];ok == false {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -66,7 +68,7 @@ func (ds *DynamicDiscoveryMaster) updateNodeInfo(nInfo *rpc.NodeInfo) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *DynamicDiscoveryMaster) addNodeInfo(nInfo *rpc.NodeInfo) {
|
func (ds *OriginDiscoveryMaster) addNodeInfo(nInfo *rpc.NodeInfo) {
|
||||||
if len(nInfo.PublicServiceList) == 0 {
|
if len(nInfo.PublicServiceList) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -81,7 +83,7 @@ func (ds *DynamicDiscoveryMaster) addNodeInfo(nInfo *rpc.NodeInfo) {
|
|||||||
ds.nodeInfo = append(ds.nodeInfo, nodeInfo)
|
ds.nodeInfo = append(ds.nodeInfo, nodeInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *DynamicDiscoveryMaster) removeNodeInfo(nodeId string) {
|
func (ds *OriginDiscoveryMaster) removeNodeInfo(nodeId string) {
|
||||||
if _,ok:= ds.mapNodeInfo[nodeId];ok == false {
|
if _,ok:= ds.mapNodeInfo[nodeId];ok == false {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -96,14 +98,14 @@ func (ds *DynamicDiscoveryMaster) removeNodeInfo(nodeId string) {
|
|||||||
delete(ds.mapNodeInfo,nodeId)
|
delete(ds.mapNodeInfo,nodeId)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *DynamicDiscoveryMaster) OnInit() error {
|
func (ds *OriginDiscoveryMaster) OnInit() error {
|
||||||
ds.mapNodeInfo = make(map[string]struct{}, 20)
|
ds.mapNodeInfo = make(map[string]struct{}, 20)
|
||||||
ds.RegRpcListener(ds)
|
ds.RegRpcListener(ds)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *DynamicDiscoveryMaster) OnStart() {
|
func (ds *OriginDiscoveryMaster) OnStart() {
|
||||||
var nodeInfo rpc.NodeInfo
|
var nodeInfo rpc.NodeInfo
|
||||||
localNodeInfo := cluster.GetLocalNodeInfo()
|
localNodeInfo := cluster.GetLocalNodeInfo()
|
||||||
nodeInfo.NodeId = localNodeInfo.NodeId
|
nodeInfo.NodeId = localNodeInfo.NodeId
|
||||||
@@ -112,11 +114,10 @@ func (ds *DynamicDiscoveryMaster) OnStart() {
|
|||||||
nodeInfo.MaxRpcParamLen = localNodeInfo.MaxRpcParamLen
|
nodeInfo.MaxRpcParamLen = localNodeInfo.MaxRpcParamLen
|
||||||
nodeInfo.Private = localNodeInfo.Private
|
nodeInfo.Private = localNodeInfo.Private
|
||||||
nodeInfo.Retire = localNodeInfo.Retire
|
nodeInfo.Retire = localNodeInfo.Retire
|
||||||
|
|
||||||
ds.addNodeInfo(&nodeInfo)
|
ds.addNodeInfo(&nodeInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *DynamicDiscoveryMaster) OnNodeConnected(nodeId string) {
|
func (ds *OriginDiscoveryMaster) OnNodeConnected(nodeId string) {
|
||||||
//没注册过结点不通知
|
//没注册过结点不通知
|
||||||
if ds.isRegNode(nodeId) == false {
|
if ds.isRegNode(nodeId) == false {
|
||||||
return
|
return
|
||||||
@@ -131,7 +132,7 @@ func (ds *DynamicDiscoveryMaster) OnNodeConnected(nodeId string) {
|
|||||||
ds.GoNode(nodeId, SubServiceDiscover, ¬ifyDiscover)
|
ds.GoNode(nodeId, SubServiceDiscover, ¬ifyDiscover)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *DynamicDiscoveryMaster) OnNodeDisconnect(nodeId string) {
|
func (ds *OriginDiscoveryMaster) OnNodeDisconnect(nodeId string) {
|
||||||
if ds.isRegNode(nodeId) == false {
|
if ds.isRegNode(nodeId) == false {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -148,13 +149,13 @@ func (ds *DynamicDiscoveryMaster) OnNodeDisconnect(nodeId string) {
|
|||||||
ds.CastGo(SubServiceDiscover, ¬ifyDiscover)
|
ds.CastGo(SubServiceDiscover, ¬ifyDiscover)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *DynamicDiscoveryMaster) RpcCastGo(serviceMethod string, args interface{}) {
|
func (ds *OriginDiscoveryMaster) RpcCastGo(serviceMethod string, args interface{}) {
|
||||||
for nodeId, _ := range ds.mapNodeInfo {
|
for nodeId, _ := range ds.mapNodeInfo {
|
||||||
ds.GoNode(nodeId, serviceMethod, args)
|
ds.GoNode(nodeId, serviceMethod, args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *DynamicDiscoveryMaster) RPC_NodeRetire(req *rpc.NodeRetireReq, res *rpc.Empty) error {
|
func (ds *OriginDiscoveryMaster) RPC_NodeRetire(req *rpc.NodeRetireReq, res *rpc.Empty) error {
|
||||||
log.Info("node is retire",log.String("nodeId",req.NodeInfo.NodeId),log.Bool("retire",req.NodeInfo.Retire))
|
log.Info("node is retire",log.String("nodeId",req.NodeInfo.NodeId),log.Bool("retire",req.NodeInfo.Retire))
|
||||||
|
|
||||||
ds.updateNodeInfo(req.NodeInfo)
|
ds.updateNodeInfo(req.NodeInfo)
|
||||||
@@ -168,7 +169,7 @@ func (ds *DynamicDiscoveryMaster) RPC_NodeRetire(req *rpc.NodeRetireReq, res *rp
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 收到注册过来的结点
|
// 收到注册过来的结点
|
||||||
func (ds *DynamicDiscoveryMaster) RPC_RegServiceDiscover(req *rpc.ServiceDiscoverReq, res *rpc.Empty) error {
|
func (ds *OriginDiscoveryMaster) RPC_RegServiceDiscover(req *rpc.ServiceDiscoverReq, res *rpc.Empty) error {
|
||||||
if req.NodeInfo == nil {
|
if req.NodeInfo == nil {
|
||||||
err := errors.New("RPC_RegServiceDiscover req is error.")
|
err := errors.New("RPC_RegServiceDiscover req is error.")
|
||||||
log.Error(err.Error())
|
log.Error(err.Error())
|
||||||
@@ -204,13 +205,15 @@ func (ds *DynamicDiscoveryMaster) RPC_RegServiceDiscover(req *rpc.ServiceDiscove
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dc *DynamicDiscoveryClient) OnInit() error {
|
func (dc *OriginDiscoveryClient) OnInit() error {
|
||||||
dc.RegRpcListener(dc)
|
dc.RegRpcListener(dc)
|
||||||
dc.mapDiscovery = map[string]map[string]struct{}{}
|
dc.mapDiscovery = map[string]map[string]struct{}{}
|
||||||
|
dc.mapMasterNetwork = map[string]string{}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dc *DynamicDiscoveryClient) addMasterNode(masterNodeId string, nodeId string) {
|
func (dc *OriginDiscoveryClient) addMasterNode(masterNodeId string, nodeId string) {
|
||||||
_, ok := dc.mapDiscovery[masterNodeId]
|
_, ok := dc.mapDiscovery[masterNodeId]
|
||||||
if ok == false {
|
if ok == false {
|
||||||
dc.mapDiscovery[masterNodeId] = map[string]struct{}{}
|
dc.mapDiscovery[masterNodeId] = map[string]struct{}{}
|
||||||
@@ -218,7 +221,7 @@ func (dc *DynamicDiscoveryClient) addMasterNode(masterNodeId string, nodeId stri
|
|||||||
dc.mapDiscovery[masterNodeId][nodeId] = struct{}{}
|
dc.mapDiscovery[masterNodeId][nodeId] = struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dc *DynamicDiscoveryClient) removeMasterNode(masterNodeId string, nodeId string) {
|
func (dc *OriginDiscoveryClient) removeMasterNode(masterNodeId string, nodeId string) {
|
||||||
mapNodeId, ok := dc.mapDiscovery[masterNodeId]
|
mapNodeId, ok := dc.mapDiscovery[masterNodeId]
|
||||||
if ok == false {
|
if ok == false {
|
||||||
return
|
return
|
||||||
@@ -227,7 +230,7 @@ func (dc *DynamicDiscoveryClient) removeMasterNode(masterNodeId string, nodeId s
|
|||||||
delete(mapNodeId, nodeId)
|
delete(mapNodeId, nodeId)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dc *DynamicDiscoveryClient) findNodeId(nodeId string) bool {
|
func (dc *OriginDiscoveryClient) findNodeId(nodeId string) bool {
|
||||||
for _, mapNodeId := range dc.mapDiscovery {
|
for _, mapNodeId := range dc.mapDiscovery {
|
||||||
_, ok := mapNodeId[nodeId]
|
_, ok := mapNodeId[nodeId]
|
||||||
if ok == true {
|
if ok == true {
|
||||||
@@ -238,22 +241,22 @@ func (dc *DynamicDiscoveryClient) findNodeId(nodeId string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dc *DynamicDiscoveryClient) OnStart() {
|
func (dc *OriginDiscoveryClient) OnStart() {
|
||||||
//2.添加并连接发现主结点
|
//2.添加并连接发现主结点
|
||||||
dc.addDiscoveryMaster()
|
dc.addDiscoveryMaster()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dc *DynamicDiscoveryClient) addDiscoveryMaster() {
|
func (dc *OriginDiscoveryClient) addDiscoveryMaster() {
|
||||||
discoveryNodeList := cluster.GetDiscoveryNodeList()
|
discoveryNodeList := cluster.GetOriginDiscoveryNodeList()
|
||||||
for i := 0; i < len(discoveryNodeList); i++ {
|
for i := 0; i < len(discoveryNodeList); i++ {
|
||||||
if discoveryNodeList[i].NodeId == cluster.GetLocalNodeInfo().NodeId {
|
if discoveryNodeList[i].NodeId == cluster.GetLocalNodeInfo().NodeId {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
dc.funSetService(&discoveryNodeList[i])
|
dc.funSetNode(&discoveryNodeList[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dc *DynamicDiscoveryClient) fullCompareDiffNode(masterNodeId string, mapNodeInfo map[string]*rpc.NodeInfo) []string {
|
func (dc *OriginDiscoveryClient) fullCompareDiffNode(masterNodeId string, mapNodeInfo map[string]*rpc.NodeInfo) []string {
|
||||||
if mapNodeInfo == nil {
|
if mapNodeInfo == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -277,7 +280,7 @@ func (dc *DynamicDiscoveryClient) fullCompareDiffNode(masterNodeId string, mapNo
|
|||||||
}
|
}
|
||||||
|
|
||||||
//订阅发现的服务通知
|
//订阅发现的服务通知
|
||||||
func (dc *DynamicDiscoveryClient) RPC_SubServiceDiscover(req *rpc.SubscribeDiscoverNotify) error {
|
func (dc *OriginDiscoveryClient) RPC_SubServiceDiscover(req *rpc.SubscribeDiscoverNotify) error {
|
||||||
mapNodeInfo := map[string]*rpc.NodeInfo{}
|
mapNodeInfo := map[string]*rpc.NodeInfo{}
|
||||||
for _, nodeInfo := range req.NodeInfo {
|
for _, nodeInfo := range req.NodeInfo {
|
||||||
//不对本地结点或者不存在任何公开服务的结点
|
//不对本地结点或者不存在任何公开服务的结点
|
||||||
@@ -285,8 +288,8 @@ func (dc *DynamicDiscoveryClient) RPC_SubServiceDiscover(req *rpc.SubscribeDisco
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if cluster.IsMasterDiscoveryNode() == false && len(nodeInfo.PublicServiceList) == 1 &&
|
if cluster.IsOriginMasterDiscoveryNode(cluster.GetLocalNodeInfo().NodeId) == false && len(nodeInfo.PublicServiceList) == 1 &&
|
||||||
nodeInfo.PublicServiceList[0] == DynamicDiscoveryClientName {
|
nodeInfo.PublicServiceList[0] == OriginDiscoveryClientName {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,7 +330,7 @@ func (dc *DynamicDiscoveryClient) RPC_SubServiceDiscover(req *rpc.SubscribeDisco
|
|||||||
cluster.TriggerDiscoveryEvent(false,nodeId,nil)
|
cluster.TriggerDiscoveryEvent(false,nodeId,nil)
|
||||||
dc.removeMasterNode(req.MasterNodeId, nodeId)
|
dc.removeMasterNode(req.MasterNodeId, nodeId)
|
||||||
if dc.findNodeId(nodeId) == false {
|
if dc.findNodeId(nodeId) == false {
|
||||||
dc.funDelService(nodeId, false)
|
dc.funDelNode(nodeId, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,24 +347,15 @@ func (dc *DynamicDiscoveryClient) RPC_SubServiceDiscover(req *rpc.SubscribeDisco
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dc *DynamicDiscoveryClient) isDiscoverNode(nodeId string) bool {
|
|
||||||
for i := 0; i < len(cluster.masterDiscoveryNodeList); i++ {
|
|
||||||
if cluster.masterDiscoveryNodeList[i].NodeId == nodeId {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
func (dc *OriginDiscoveryClient) OnNodeConnected(nodeId string) {
|
||||||
}
|
|
||||||
|
|
||||||
func (dc *DynamicDiscoveryClient) OnNodeConnected(nodeId string) {
|
|
||||||
dc.regServiceDiscover(nodeId)
|
dc.regServiceDiscover(nodeId)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dc *DynamicDiscoveryClient) OnRetire(){
|
func (dc *OriginDiscoveryClient) OnRetire(){
|
||||||
dc.bRetire = true
|
dc.bRetire = true
|
||||||
|
|
||||||
masterNodeList := cluster.GetDiscoveryNodeList()
|
masterNodeList := cluster.GetOriginDiscoveryNodeList()
|
||||||
for i:=0;i<len(masterNodeList);i++{
|
for i:=0;i<len(masterNodeList);i++{
|
||||||
var nodeRetireReq rpc.NodeRetireReq
|
var nodeRetireReq rpc.NodeRetireReq
|
||||||
|
|
||||||
@@ -380,8 +374,8 @@ func (dc *DynamicDiscoveryClient) OnRetire(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dc *DynamicDiscoveryClient) regServiceDiscover(nodeId string){
|
func (dc *OriginDiscoveryClient) regServiceDiscover(nodeId string){
|
||||||
nodeInfo := cluster.GetMasterDiscoveryNodeInfo(nodeId)
|
nodeInfo := cluster.getOriginMasterDiscoveryNodeInfo(nodeId)
|
||||||
if nodeInfo == nil {
|
if nodeInfo == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -411,27 +405,7 @@ func (dc *DynamicDiscoveryClient) regServiceDiscover(nodeId string){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dc *DynamicDiscoveryClient) canDiscoveryService(fromMasterNodeId string,serviceName string) bool{
|
func (dc *OriginDiscoveryClient) setNodeInfo(masterNodeId string,nodeInfo *rpc.NodeInfo) bool{
|
||||||
canDiscovery := true
|
|
||||||
|
|
||||||
for i:=0;i<len(cluster.GetLocalNodeInfo().MasterDiscoveryService);i++{
|
|
||||||
masterNodeId := cluster.GetLocalNodeInfo().MasterDiscoveryService[i].MasterNodeId
|
|
||||||
|
|
||||||
if masterNodeId == fromMasterNodeId || masterNodeId == rpc.NodeIdNull {
|
|
||||||
canDiscovery = false
|
|
||||||
|
|
||||||
for _,discoveryService := range cluster.GetLocalNodeInfo().MasterDiscoveryService[i].DiscoveryService {
|
|
||||||
if discoveryService == serviceName {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return canDiscovery
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dc *DynamicDiscoveryClient) setNodeInfo(masterNodeId string,nodeInfo *rpc.NodeInfo) bool{
|
|
||||||
if nodeInfo == nil || nodeInfo.Private == true || nodeInfo.NodeId == dc.localNodeId {
|
if nodeInfo == nil || nodeInfo.Private == true || nodeInfo.NodeId == dc.localNodeId {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -439,7 +413,7 @@ func (dc *DynamicDiscoveryClient) setNodeInfo(masterNodeId string,nodeInfo *rpc.
|
|||||||
//筛选关注的服务
|
//筛选关注的服务
|
||||||
var discoverServiceSlice = make([]string, 0, 24)
|
var discoverServiceSlice = make([]string, 0, 24)
|
||||||
for _, pubService := range nodeInfo.PublicServiceList {
|
for _, pubService := range nodeInfo.PublicServiceList {
|
||||||
if dc.canDiscoveryService(masterNodeId,pubService) == true {
|
if cluster.CanDiscoveryService(masterNodeId,pubService) == true {
|
||||||
discoverServiceSlice = append(discoverServiceSlice,pubService)
|
discoverServiceSlice = append(discoverServiceSlice,pubService)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -457,23 +431,66 @@ func (dc *DynamicDiscoveryClient) setNodeInfo(masterNodeId string,nodeInfo *rpc.
|
|||||||
nInfo.Retire = nodeInfo.Retire
|
nInfo.Retire = nodeInfo.Retire
|
||||||
nInfo.Private = nodeInfo.Private
|
nInfo.Private = nodeInfo.Private
|
||||||
|
|
||||||
dc.funSetService(&nInfo)
|
dc.funSetNode(&nInfo)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dc *DynamicDiscoveryClient) OnNodeDisconnect(nodeId string) {
|
func (dc *OriginDiscoveryClient) OnNodeDisconnect(nodeId string) {
|
||||||
//将Discard结点清理
|
//将Discard结点清理
|
||||||
cluster.DiscardNode(nodeId)
|
cluster.DiscardNode(nodeId)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dc *DynamicDiscoveryClient) InitDiscovery(localNodeId string, funDelNode FunDelNode, funSetNodeInfo FunSetNodeInfo) error {
|
func (dc *OriginDiscoveryClient) InitDiscovery(localNodeId string, funDelNode FunDelNode, funSetNode FunSetNode) error {
|
||||||
dc.localNodeId = localNodeId
|
dc.localNodeId = localNodeId
|
||||||
dc.funDelService = funDelNode
|
dc.funDelNode = funDelNode
|
||||||
dc.funSetService = funSetNodeInfo
|
dc.funSetNode = funSetNode
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dc *DynamicDiscoveryClient) OnNodeStop() {
|
func (cls *Cluster) checkOriginDiscovery(localNodeId string) (bool, bool) {
|
||||||
|
var localMaster bool //本结点是否为Master结点
|
||||||
|
var hasMaster bool //是否配置Master服务
|
||||||
|
|
||||||
|
//遍历所有结点
|
||||||
|
for _, nodeInfo := range cls.discoveryInfo.Origin {
|
||||||
|
if nodeInfo.NodeId == localNodeId {
|
||||||
|
localMaster = true
|
||||||
|
}
|
||||||
|
hasMaster = true
|
||||||
|
}
|
||||||
|
|
||||||
|
//返回查询结果
|
||||||
|
return localMaster, hasMaster
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cls *Cluster) AddDiscoveryService(serviceName string, bPublicService bool) {
|
||||||
|
addServiceList := append([]string{},serviceName)
|
||||||
|
cls.localNodeInfo.ServiceList = append(addServiceList,cls.localNodeInfo.ServiceList...)
|
||||||
|
if bPublicService {
|
||||||
|
cls.localNodeInfo.PublicServiceList = append(cls.localNodeInfo.PublicServiceList, serviceName)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := cls.mapServiceNode[serviceName]; ok == false {
|
||||||
|
cls.mapServiceNode[serviceName] = map[string]struct{}{}
|
||||||
|
}
|
||||||
|
cls.mapServiceNode[serviceName][cls.localNodeInfo.NodeId] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (cls *Cluster) IsOriginMasterDiscoveryNode(nodeId string) bool {
|
||||||
|
//return cls.GetMasterDiscoveryNodeInfo(cls.GetLocalNodeInfo().NodeId) != nil
|
||||||
|
return cls.getOriginMasterDiscoveryNodeInfo(nodeId) != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cls *Cluster) getOriginMasterDiscoveryNodeInfo(nodeId string) *NodeInfo {
|
||||||
|
for i := 0; i < len(cls.discoveryInfo.Origin); i++ {
|
||||||
|
if cls.discoveryInfo.Origin[i].NodeId == nodeId {
|
||||||
|
return &cls.discoveryInfo.Origin[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
@@ -8,15 +8,127 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var json = jsoniter.ConfigCompatibleWithStandardLibrary
|
var json = jsoniter.ConfigCompatibleWithStandardLibrary
|
||||||
|
|
||||||
|
type EtcdList struct {
|
||||||
|
NetworkName []string
|
||||||
|
Endpoints []string
|
||||||
|
}
|
||||||
|
|
||||||
|
type EtcdDiscovery struct {
|
||||||
|
DialTimeoutMillisecond time.Duration
|
||||||
|
TTLSecond int64
|
||||||
|
|
||||||
|
EtcdList []EtcdList
|
||||||
|
}
|
||||||
|
|
||||||
|
type DiscoveryType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
InvalidType = 0
|
||||||
|
OriginType = 1
|
||||||
|
EtcdType = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
type DiscoveryInfo struct {
|
||||||
|
discoveryType DiscoveryType
|
||||||
|
Etcd *EtcdDiscovery //etcd
|
||||||
|
Origin []NodeInfo //orign
|
||||||
|
}
|
||||||
|
|
||||||
type NodeInfoList struct {
|
type NodeInfoList struct {
|
||||||
MasterDiscoveryNode []NodeInfo //用于服务发现Node
|
Discovery DiscoveryInfo
|
||||||
NodeList []NodeInfo
|
NodeList []NodeInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *DiscoveryInfo) getDiscoveryType() DiscoveryType{
|
||||||
|
return d.discoveryType
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DiscoveryInfo) setDiscovery(discoveryInfo *DiscoveryInfo) error{
|
||||||
|
var err error
|
||||||
|
err = d.setOrigin(discoveryInfo.Origin)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = d.setEtcd(discoveryInfo.Etcd)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DiscoveryInfo) setEtcd(etcd *EtcdDiscovery) error{
|
||||||
|
if etcd == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.discoveryType != InvalidType {
|
||||||
|
return fmt.Errorf("Repeat configuration of Discovery")
|
||||||
|
}
|
||||||
|
|
||||||
|
etcd.TTLSecond = etcd.TTLSecond
|
||||||
|
etcd.DialTimeoutMillisecond = etcd.DialTimeoutMillisecond * time.Millisecond
|
||||||
|
|
||||||
|
//Endpoints不允许重复
|
||||||
|
mapAddr:=make (map[string]struct{})
|
||||||
|
for _, n := range etcd.EtcdList {
|
||||||
|
for _,endPoint := range n.Endpoints {
|
||||||
|
if _,ok:=mapAddr[endPoint];ok == true {
|
||||||
|
return fmt.Errorf("etcd discovery config Etcd.EtcdList.Endpoints %+v is repeat",endPoint)
|
||||||
|
}
|
||||||
|
mapAddr[endPoint] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
//networkName不允许重复
|
||||||
|
mapNetworkName := make(map[string]struct{})
|
||||||
|
for _,netName := range n.NetworkName{
|
||||||
|
if _,ok := mapNetworkName[netName];ok == true {
|
||||||
|
return fmt.Errorf("etcd discovery config Etcd.EtcdList.NetworkName %+v is repeat",n.NetworkName)
|
||||||
|
}
|
||||||
|
|
||||||
|
mapNetworkName[netName] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Etcd = etcd
|
||||||
|
d.discoveryType = EtcdType
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DiscoveryInfo) setOrigin(nodeInfos []NodeInfo) error{
|
||||||
|
if nodeInfos == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.discoveryType != InvalidType {
|
||||||
|
return fmt.Errorf("Repeat configuration of Discovery")
|
||||||
|
}
|
||||||
|
|
||||||
|
mapListenAddr := make(map[string]struct{})
|
||||||
|
mapNodeId := make(map[string]struct{})
|
||||||
|
for _, n := range nodeInfos {
|
||||||
|
if _, ok := mapListenAddr[n.ListenAddr]; ok == true {
|
||||||
|
return fmt.Errorf("discovery config Origin.ListenAddr %s is repeat", n.ListenAddr)
|
||||||
|
}
|
||||||
|
mapListenAddr[n.ListenAddr] = struct{}{}
|
||||||
|
|
||||||
|
if _, ok := mapNodeId[n.NodeId]; ok == true {
|
||||||
|
return fmt.Errorf("discovery config Origin.NodeId %s is repeat", n.NodeId)
|
||||||
|
}
|
||||||
|
mapNodeId[n.NodeId] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Origin = nodeInfos
|
||||||
|
d.discoveryType = OriginType
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (cls *Cluster) ReadClusterConfig(filepath string) (*NodeInfoList, error) {
|
func (cls *Cluster) ReadClusterConfig(filepath string) (*NodeInfoList, error) {
|
||||||
c := &NodeInfoList{}
|
c := &NodeInfoList{}
|
||||||
d, err := os.ReadFile(filepath)
|
d, err := os.ReadFile(filepath)
|
||||||
@@ -66,25 +178,32 @@ func (cls *Cluster) readServiceConfig(filepath string) (interface{}, map[string]
|
|||||||
return GlobalCfg, serviceConfig, mapNodeService, nil
|
return GlobalCfg, serviceConfig, mapNodeService, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cls *Cluster) readLocalClusterConfig(nodeId string) ([]NodeInfo, []NodeInfo, error) {
|
func (cls *Cluster) readLocalClusterConfig(nodeId string) (DiscoveryInfo, []NodeInfo, error) {
|
||||||
var nodeInfoList []NodeInfo
|
var nodeInfoList []NodeInfo
|
||||||
var masterDiscoverNodeList []NodeInfo
|
var discoveryInfo DiscoveryInfo
|
||||||
|
|
||||||
clusterCfgPath := strings.TrimRight(configDir, "/") + "/cluster"
|
clusterCfgPath := strings.TrimRight(configDir, "/") + "/cluster"
|
||||||
fileInfoList, err := os.ReadDir(clusterCfgPath)
|
fileInfoList, err := os.ReadDir(clusterCfgPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("Read dir %s is fail :%+v", clusterCfgPath, err)
|
return discoveryInfo, nil, fmt.Errorf("Read dir %s is fail :%+v", clusterCfgPath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
//读取任何文件,只读符合格式的配置,目录下的文件可以自定义分文件
|
//读取任何文件,只读符合格式的配置,目录下的文件可以自定义分文件
|
||||||
for _, f := range fileInfoList {
|
for _, f := range fileInfoList {
|
||||||
if f.IsDir() == false {
|
if f.IsDir() == false {
|
||||||
filePath := strings.TrimRight(strings.TrimRight(clusterCfgPath, "/"), "\\") + "/" + f.Name()
|
filePath := strings.TrimRight(strings.TrimRight(clusterCfgPath, "/"), "\\") + "/" + f.Name()
|
||||||
localNodeInfoList, err := cls.ReadClusterConfig(filePath)
|
fileNodeInfoList, rerr := cls.ReadClusterConfig(filePath)
|
||||||
if err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("read file path %s is error:%+v", filePath, err)
|
if rerr != nil {
|
||||||
|
return discoveryInfo, nil, fmt.Errorf("read file path %s is error:%+v", filePath, rerr)
|
||||||
}
|
}
|
||||||
masterDiscoverNodeList = append(masterDiscoverNodeList, localNodeInfoList.MasterDiscoveryNode...)
|
|
||||||
for _, nodeInfo := range localNodeInfoList.NodeList {
|
err = discoveryInfo.setDiscovery(&fileNodeInfoList.Discovery)
|
||||||
|
if err != nil {
|
||||||
|
return discoveryInfo,nil,err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, nodeInfo := range fileNodeInfoList.NodeList {
|
||||||
if nodeInfo.NodeId == nodeId || nodeId == rpc.NodeIdNull {
|
if nodeInfo.NodeId == nodeId || nodeId == rpc.NodeIdNull {
|
||||||
nodeInfoList = append(nodeInfoList, nodeInfo)
|
nodeInfoList = append(nodeInfoList, nodeInfo)
|
||||||
}
|
}
|
||||||
@@ -93,7 +212,7 @@ func (cls *Cluster) readLocalClusterConfig(nodeId string) ([]NodeInfo, []NodeInf
|
|||||||
}
|
}
|
||||||
|
|
||||||
if nodeId != rpc.NodeIdNull && (len(nodeInfoList) != 1) {
|
if nodeId != rpc.NodeIdNull && (len(nodeInfoList) != 1) {
|
||||||
return nil, nil, fmt.Errorf("%d configurations were found for the configuration with node ID %d!", len(nodeInfoList), nodeId)
|
return discoveryInfo, nil, fmt.Errorf("%d configurations were found for the configuration with node ID %d!", len(nodeInfoList), nodeId)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, _ := range nodeInfoList {
|
for i, _ := range nodeInfoList {
|
||||||
@@ -107,7 +226,7 @@ func (cls *Cluster) readLocalClusterConfig(nodeId string) ([]NodeInfo, []NodeInf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return masterDiscoverNodeList, nodeInfoList, nil
|
return discoveryInfo, nodeInfoList, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cls *Cluster) readLocalService(localNodeId string) error {
|
func (cls *Cluster) readLocalService(localNodeId string) error {
|
||||||
@@ -214,34 +333,18 @@ func (cls *Cluster) parseLocalCfg() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cls *Cluster) checkDiscoveryNodeList(discoverMasterNode []NodeInfo) bool {
|
|
||||||
for i := 0; i < len(discoverMasterNode)-1; i++ {
|
|
||||||
for j := i + 1; j < len(discoverMasterNode); j++ {
|
|
||||||
if discoverMasterNode[i].NodeId == discoverMasterNode[j].NodeId ||
|
|
||||||
discoverMasterNode[i].ListenAddr == discoverMasterNode[j].ListenAddr {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cls *Cluster) InitCfg(localNodeId string) error {
|
func (cls *Cluster) InitCfg(localNodeId string) error {
|
||||||
cls.localServiceCfg = map[string]interface{}{}
|
cls.localServiceCfg = map[string]interface{}{}
|
||||||
cls.mapRpc = map[string]*NodeRpcInfo{}
|
cls.mapRpc = map[string]*NodeRpcInfo{}
|
||||||
cls.mapServiceNode = map[string]map[string]struct{}{}
|
cls.mapServiceNode = map[string]map[string]struct{}{}
|
||||||
|
|
||||||
//加载本地结点的NodeList配置
|
//加载本地结点的NodeList配置
|
||||||
discoveryNode, nodeInfoList, err := cls.readLocalClusterConfig(localNodeId)
|
discoveryInfo, nodeInfoList, err := cls.readLocalClusterConfig(localNodeId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cls.localNodeInfo = nodeInfoList[0]
|
cls.localNodeInfo = nodeInfoList[0]
|
||||||
if cls.checkDiscoveryNodeList(discoveryNode) == false {
|
cls.discoveryInfo = discoveryInfo
|
||||||
return fmt.Errorf("DiscoveryNode config is error!")
|
|
||||||
}
|
|
||||||
cls.masterDiscoveryNodeList = discoveryNode
|
|
||||||
|
|
||||||
//读取本地服务配置
|
//读取本地服务配置
|
||||||
err = cls.readLocalService(localNodeId)
|
err = cls.readLocalService(localNodeId)
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package cluster
|
package cluster
|
||||||
|
|
||||||
|
|
||||||
type OperType int
|
type OperType int
|
||||||
|
|
||||||
type FunDelNode func (nodeId string,immediately bool)
|
type FunDelNode func (nodeId string,immediately bool)
|
||||||
type FunSetNodeInfo func(nodeInfo *NodeInfo)
|
type FunSetNode func(nodeInfo *NodeInfo)
|
||||||
|
|
||||||
type IServiceDiscovery interface {
|
type IServiceDiscovery interface {
|
||||||
InitDiscovery(localNodeId string,funDelNode FunDelNode,funSetNodeInfo FunSetNodeInfo) error
|
InitDiscovery(localNodeId string,funDelNode FunDelNode,funSetNodeInfo FunSetNode) error
|
||||||
OnNodeStop()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,8 +14,9 @@ const (
|
|||||||
Sys_Event_DiscoverService EventType = -7
|
Sys_Event_DiscoverService EventType = -7
|
||||||
Sys_Event_DiscardGoroutine EventType = -8
|
Sys_Event_DiscardGoroutine EventType = -8
|
||||||
Sys_Event_QueueTaskFinish EventType = -9
|
Sys_Event_QueueTaskFinish EventType = -9
|
||||||
Sys_Event_Retire EventType = -10
|
Sys_Event_Retire EventType = -10
|
||||||
|
Sys_Event_EtcdDiscovery EventType = -11
|
||||||
|
|
||||||
Sys_Event_User_Define EventType = 1
|
Sys_Event_User_Define EventType = 1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -156,7 +156,8 @@ func initNode(id string) {
|
|||||||
nodeId = id
|
nodeId = id
|
||||||
err := cluster.GetCluster().Init(GetNodeId(), Setup)
|
err := cluster.GetCluster().Init(GetNodeId(), Setup)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("read system config is error ",log.ErrorAttr("error",err))
|
log.Error("Init cluster fail",log.ErrorAttr("error",err))
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = initLog()
|
err = initLog()
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import "errors"
|
import (
|
||||||
|
"github.com/duanhf2012/origin/v2/log"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
//本地所有的service
|
//本地所有的service
|
||||||
var mapServiceName map[string]IService
|
var mapServiceName map[string]IService
|
||||||
@@ -23,8 +26,8 @@ func Init() {
|
|||||||
for _,s := range setupServiceList {
|
for _,s := range setupServiceList {
|
||||||
err := s.OnInit()
|
err := s.OnInit()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs := errors.New("Failed to initialize "+s.GetName()+" service:"+err.Error())
|
log.SError("Failed to initialize "+s.GetName()+" service:"+err.Error())
|
||||||
panic(errs)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user