sequence

This paper mainly studies the NamingClient of NACOS-SDK-Go

NamingClient

Nacos – SDK – go – v0.3.2 / clients/naming_client/naming_client. Go

type NamingClient struct {
	nacos_client.INacosClient
	hostReactor  HostReactor
	serviceProxy NamingProxy
	subCallback  SubscribeCallback
	beatReactor  BeatReactor
	indexMap     cache.ConcurrentMap
}
Copy the code
  • NamingClient defines the hostReactor, serviceProxy, subCallback, beatReactor, and indexMap attributes

NewNamingClient

Nacos – SDK – go – v0.3.2 / clients/naming_client/naming_client. Go

func NewNamingClient(nc nacos_client.INacosClient) (NamingClient, error) {
	naming := NamingClient{}
	clientConfig, err :=
		nc.GetClientConfig()
	iferr ! = nil {return naming, err
	}
	serverConfig, err := nc.GetServerConfig()
	iferr ! = nil {return naming, err
	}
	httpAgent, err := nc.GetHttpAgent()
	iferr ! = nil {return naming, err
	}
	err = logger.InitLog(clientConfig.LogDir)
	iferr ! = nil {return naming, err
	}
	naming.subCallback = NewSubscribeCallback()
	naming.serviceProxy, err = NewNamingProxy(clientConfig, serverConfig, httpAgent)
	iferr ! = nil {return naming, err
	}
	naming.hostReactor = NewHostReactor(naming.serviceProxy, clientConfig.CacheDir+string(os.PathSeparator)+"naming",
		clientConfig.UpdateThreadNum, clientConfig.NotLoadCacheAtStart, naming.subCallback, clientConfig.UpdateCacheWhenEmpty)
	naming.beatReactor = NewBeatReactor(naming.serviceProxy, clientConfig.BeatInterval)
	naming.indexMap = cache.NewConcurrentMap()

	return naming, nil
}
Copy the code
  • The NewNamingClient method creates the NamingClient and sets its subCallback, serviceProxy, hostReactor, beatReactor, and indexMap properties

RegisterInstance

Nacos – SDK – go – v0.3.2 / clients/naming_client/naming_client. Go

Func (sc *NamingClient) RegisterInstance(param vo.RegisterInstanceParam) (bool, error) {if param.GroupName == "" {
		param.GroupName = constant.DEFAULT_GROUP
	}
	instance := model.Instance{
		Ip:          param.Ip,
		Port:        param.Port,
		Metadata:    param.Metadata,
		ClusterName: param.ClusterName,
		Healthy:     param.Healthy,
		Enable:      param.Enable,
		Weight:      param.Weight,
		Ephemeral:   param.Ephemeral,
	}
	beatInfo := model.BeatInfo{
		Ip:          param.Ip,
		Port:        param.Port,
		Metadata:    param.Metadata,
		ServiceName: utils.GetGroupName(param.ServiceName, param.GroupName),
		Cluster:     param.ClusterName,
		Weight:      param.Weight,
		Period:      utils.GetDurationWithDefault(param.Metadata, constant.HEART_BEAT_INTERVAL, time.Second*5),
	}
	_, err := sc.serviceProxy.RegisterInstance(utils.GetGroupName(param.ServiceName, param.GroupName), param.GroupName, instance)
	iferr ! = nil {return false, err
	}
	if instance.Ephemeral {
		sc.beatReactor.AddBeatInfo(utils.GetGroupName(param.ServiceName, param.GroupName), beatInfo)
	}
	return true, nil

}
Copy the code
  • The RegisterInstance method builds an instance from RegisterInstanceParam, Then by sc. ServiceProxy. RegisterInstance (utils GetGroupName (param. ServiceName, param. GroupName), param. GroupName, Instance) deregister; If the instance is Ephemeral type, then execute sc. BeatReactor. AddBeatInfo (utils. GetGroupName (param. ServiceName, param. GroupName), beatInfo)

DeregisterInstance

Nacos – SDK – go – v0.3.2 / clients/naming_client/naming_client. Go

/ / cancel service instance func (sc * NamingClient) DeregisterInstance (param vo. DeregisterInstanceParam) (bool, error) {if param.GroupName == "" {
		param.GroupName = constant.DEFAULT_GROUP
	}
	sc.beatReactor.RemoveBeatInfo(utils.GetGroupName(param.ServiceName, param.GroupName), param.Ip, param.Port)

	_, err := sc.serviceProxy.DeregisterInstance(utils.GetGroupName(param.ServiceName, param.GroupName), param.Ip, param.Port, param.Cluster, param.Ephemeral)
	iferr ! = nil {return false, err
	}
	return true, nil
}
Copy the code
  • DeregisterInstance method performs sc. BeatReactor. RemoveBeatInfo and sc. ServiceProxy. DeregisterInstance

GetService

Nacos – SDK – go – v0.3.2 / clients/naming_client/naming_client. Go

Func (sc *NamingClient) GetService(param vo.getServiceParam) (model.service, error) {if param.GroupName == "" {
		param.GroupName = constant.DEFAULT_GROUP
	}
	service := sc.hostReactor.GetServiceInfo(utils.GetGroupName(param.ServiceName, param.GroupName), strings.Join(param.Clusters, ","))
	return service, nil
}
Copy the code
  • GetService method by sc. HostReactor. GetServiceInfo to query the service information

GetAllServicesInfo

Nacos – SDK – go – v0.3.2 / clients/naming_client/naming_client. Go

func (sc *NamingClient) GetAllServicesInfo(param vo.GetAllServiceInfoParam) ([]model.Service, error) {
	if param.GroupName == "" {
		param.GroupName = constant.DEFAULT_GROUP
	}
	if param.NameSpace == "" {
		param.NameSpace = constant.DEFAULT_NAMESPACE_ID
	}
	service := sc.hostReactor.GetAllServiceInfo(param.NameSpace, param.GroupName, strings.Join(param.Clusters, ","))
	return service, nil
}
Copy the code
  • GetAllServicesInfo method by sc. HostReactor. GetAllServiceInfo to query all of the information service

SelectAllInstances

Nacos – SDK – go – v0.3.2 / clients/naming_client/naming_client. Go

func (sc *NamingClient) SelectAllInstances(param vo.SelectAllInstancesParam) ([]model.Instance, error) {
	if param.GroupName == "" {
		param.GroupName = constant.DEFAULT_GROUP
	}
	service := sc.hostReactor.GetServiceInfo(utils.GetGroupName(param.ServiceName, param.GroupName), strings.Join(param.Clusters, ","))
	if service.Hosts == nil || len(service.Hosts) == 0 {
		return []model.Instance{}, errors.New("instance list is empty!")}return service.Hosts, nil
}
Copy the code
  • SelectAllInstances method by sc. HostReactor. GetServiceInfo service information, and then return to service. The Hosts

SelectInstances

Nacos – SDK – go – v0.3.2 / clients/naming_client/naming_client. Go

func (sc *NamingClient) SelectInstances(param vo.SelectInstancesParam) ([]model.Instance, error) {
	if param.GroupName == "" {
		param.GroupName = constant.DEFAULT_GROUP
	}
	service := sc.hostReactor.GetServiceInfo(utils.GetGroupName(param.ServiceName, param.GroupName), strings.Join(param.Clusters, ","))
	return sc.selectInstances(service, param.HealthyOnly)
}

func (sc *NamingClient) selectInstances(service model.Service, healthy bool) ([]model.Instance, error) {
	if service.Hosts == nil || len(service.Hosts) == 0 {
		return []model.Instance{}, errors.New("instance list is empty!")
	}
	hosts := service.Hosts
	var result []model.Instance
	for _, host := range hosts {
		if host.Healthy == healthy && host.Enable && host.Weight > 0 {
			result = append(result, host)
		}
	}
	return result, nil
}
Copy the code
  • SelectInstances method by sc. HostReactor. GetServiceInfo service information, Then obtain healthy instances through SC. selectInstances(Service, param.healthyOnly)

SelectOneHealthyInstance

Nacos – SDK – go – v0.3.2 / clients/naming_client/naming_client. Go

func (sc *NamingClient) SelectOneHealthyInstance(param vo.SelectOneHealthInstanceParam) (*model.Instance, error) {
	if param.GroupName == "" {
		param.GroupName = constant.DEFAULT_GROUP
	}
	service := sc.hostReactor.GetServiceInfo(utils.GetGroupName(param.ServiceName, param.GroupName), strings.Join(param.Clusters, ","))
	return sc.selectOneHealthyInstances(service)
}

func (sc *NamingClient) selectOneHealthyInstances(service model.Service) (*model.Instance, error) {
	if service.Hosts == nil || len(service.Hosts) == 0 {
		return nil, errors.New("instance list is empty!")
	}
	hosts := service.Hosts
	var result []model.Instance
	mw := 0
	for _, host := range hosts {
		if host.Healthy && host.Enable && host.Weight > 0 {
			cw := int(math.Ceil(host.Weight))
			if cw > mw {
				mw = cw
			}
			result = append(result, host)
		}
	}
	if len(result) == 0 {
		return nil, errors.New("healthy instance list is empty!")
	}

	randomInstances := random(result, mw)
	key := utils.GetServiceCacheKey(service.Name, service.Clusters)
	i, indexOk := sc.indexMap.Get(key)
	var index int

	if! indexOk { index = rand.Intn(len(randomInstances)) }else {
		index = i.(int)
		index += 1
		if index >= len(randomInstances) {
			index = index % len(randomInstances)
		}
	}

	sc.indexMap.Set(key, index)
	return &randomInstances[index], nil
}
Copy the code
  • SelectOneHealthyInstance method by sc. HostReactor. GetServiceInfo service information, By sc. SelectOneHealthyInstances (service) to choose a healthy instance

Subscribe

Nacos – SDK – go – v0.3.2 / clients/naming_client/naming_client. Go

Subscribe(param *vo.SubscribeParam) error {Subscribe(sc *NamingClient) Subscribe(param *vo.if param.GroupName == "" {
		param.GroupName = constant.DEFAULT_GROUP
	}
	serviceParam := vo.GetServiceParam{
		ServiceName: param.ServiceName,
		GroupName:   param.GroupName,
		Clusters:    param.Clusters,
	}

	sc.subCallback.AddCallbackFuncs(utils.GetGroupName(param.ServiceName, param.GroupName), strings.Join(param.Clusters, ","), &param.SubscribeCallback)
	_, err := sc.GetService(serviceParam)
	iferr ! = nil {return err
	}
	return nil
}
Copy the code
  • The Subscribe method by sc. SubCallback. AddCallbackFuncs to register the callback

Unsubscribe

Nacos – SDK – go – v0.3.2 / clients/naming_client/naming_client. Go

Func (sc *NamingClient) Unsubscribe(param *vo.SubscribeParam) error { sc.subCallback.RemoveCallbackFuncs(utils.GetGroupName(param.ServiceName, param.GroupName), strings.Join(param.Clusters,","), &param.SubscribeCallback)
	return nil
}
Copy the code
  • Unsubscribe method by sc. SubCallback. RemoveCallbackFuncs to cancel callback

summary

Nacos-sdk-go NamingClient provides RegisterInstance, DeregisterInstance, GetService, GetAllServicesInfo, SelectAllInstances, SelectI Nstances, SelectOneHealthyInstance, Subscribe, Unsubscribe method

doc

  • naming_client