聊聊nacos-sdk-go的BeatReactor

一个人想着一个人 提交于 2020-07-29 07:47:25

本文主要研究一下nacos-sdk-go的BeatReactor

BeatReactor

nacos-sdk-go-v0.3.2/clients/naming_client/beat_reactor.go

type BeatReactor struct {
	beatMap             cache.ConcurrentMap
	serviceProxy        NamingProxy
	clientBeatInterval  int64
	beatThreadCount     int
	beatThreadSemaphore *nsema.Semaphore
	beatRecordMap       cache.ConcurrentMap
}
  • BeatReactor定义了beatMap、serviceProxy、clientBeatInterval、beatThreadCount、beatThreadSemaphore、beatRecordMap属性

NewBeatReactor

nacos-sdk-go-v0.3.2/clients/naming_client/beat_reactor.go

func NewBeatReactor(serviceProxy NamingProxy, clientBeatInterval int64) BeatReactor {
	br := BeatReactor{}
	if clientBeatInterval <= 0 {
		clientBeatInterval = 5 * 1000
	}
	br.beatMap = cache.NewConcurrentMap()
	br.serviceProxy = serviceProxy
	br.clientBeatInterval = clientBeatInterval
	br.beatThreadCount = Default_Beat_Thread_Num
	br.beatRecordMap = cache.NewConcurrentMap()
	br.beatThreadSemaphore = nsema.NewSemaphore(br.beatThreadCount)
	return br
}
  • NewBeatReactor方法创建了BeatReactor,并初始化其属性

AddBeatInfo

nacos-sdk-go-v0.3.2/clients/naming_client/beat_reactor.go

func (br *BeatReactor) AddBeatInfo(serviceName string, beatInfo model.BeatInfo) {
	log.Printf("[INFO] adding beat: <%s> to beat map.\n", utils.ToJsonString(beatInfo))
	k := buildKey(serviceName, beatInfo.Ip, beatInfo.Port)
	br.beatMap.Set(k, &beatInfo)
	go br.sendInstanceBeat(k, &beatInfo)
}
  • AddBeatInfo方法通过buildKey构建key,然后将其放进去beatMap,之后异步执行br.sendInstanceBeat

RemoveBeatInfo

nacos-sdk-go-v0.3.2/clients/naming_client/beat_reactor.go

func (br *BeatReactor) RemoveBeatInfo(serviceName string, ip string, port uint64) {
	log.Printf("[INFO] remove beat: %s@%s:%d from beat map.\n", serviceName, ip, port)
	k := buildKey(serviceName, ip, port)
	data, exist := br.beatMap.Get(k)
	if exist {
		beatInfo := data.(*model.BeatInfo)
		beatInfo.Stopped = true
	}
	br.beatMap.Remove(k)
}
  • RemoveBeatInfo方法将指定key从beatMap移除,对于已经在beatMap中的设置其Stopped为true

sendInstanceBeat

nacos-sdk-go-v0.3.2/clients/naming_client/beat_reactor.go

func (br *BeatReactor) sendInstanceBeat(k string, beatInfo *model.BeatInfo) {
	for {
		br.beatThreadSemaphore.Acquire()
		//如果当前实例注销,则进行停止心跳
		if beatInfo.Stopped {
			log.Printf("[INFO] intance[%s] stop heartBeating\n", k)
			br.beatThreadSemaphore.Release()
			return
		}

		//进行心跳通信
		beatInterval, err := br.serviceProxy.SendBeat(*beatInfo)
		if err != nil {
			log.Printf("[ERROR]:beat to server return error:%s \n", err.Error())
			br.beatThreadSemaphore.Release()
			t := time.NewTimer(beatInfo.Period)
			<-t.C
			continue
		}
		if beatInterval > 0 {
			beatInfo.Period = time.Duration(time.Millisecond.Nanoseconds() * beatInterval)
		}

		br.beatRecordMap.Set(k, utils.CurrentMillis())
		br.beatThreadSemaphore.Release()

		t := time.NewTimer(beatInfo.Period)
		<-t.C
	}
}
  • sendInstanceBeat方法先执行br.beatThreadSemaphore.Acquire(),之后通过br.serviceProxy.SendBeat(*beatInfo)来发送beat,之后执行br.beatThreadSemaphore.Release(),然后新创建time.NewTimer(beatInfo.Period)

小结

BeatReactor定义了beatMap、serviceProxy、clientBeatInterval、beatThreadCount、beatThreadSemaphore、beatRecordMap属性;它提供了NewBeatReactor、AddBeatInfo、RemoveBeatInfo方法

doc

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!