上文說到了服務(wù)實(shí)例的正常上下線,都是實(shí)例主動調(diào)接口完成的陡叠。但是如果實(shí)例被kill -9呢,就不會主動通知下線了译红。
如何處理這種情況岭妖,這個才是服務(wù)發(fā)現(xiàn)的重點(diǎn)了。
解決的辦法就是 心跳+定時任務(wù)去判斷假夺,不過這里定時任務(wù)的分配也是有講究了斋攀。
1 心跳
nacos源碼分析——如何做心跳續(xù)約 中說到了,服務(wù)實(shí)例的心跳調(diào)用/clientBeat接口侧蘸,會更新lastBeat為當(dāng)前時間。
但是這個lastBeat時間要如何用起來呢穿稳?
2 定時任務(wù)
VirtualClusterDomain 會起個定時任務(wù)
一段時間沒有收到心跳晌坤,就刪除這個實(shí)例
3 定時任務(wù)的分配
上面的做法有個問題,nacos有很多服務(wù)器它改,每個服務(wù)器都要定時任務(wù)檢查所有的服務(wù)列表嗎商乎?
如果重復(fù)的做,會有很大的資源浪費(fèi)鲜戒,而且如果都檢查到超時了抹凳,都和leader通信說要下線,對網(wǎng)絡(luò)的負(fù)擔(dān)也比較高却桶。
解決的辦法就是 服務(wù)名hash % nacos服務(wù)器數(shù)目 蔗牡,得到其中一臺 nacos服務(wù)器辩越,如果是自己的話,就開始檢查這個服務(wù)的實(shí)例列表黔攒,如果不是就跳過。
每個nacos服務(wù)器都這樣去檢查不傅,自然會覆蓋到所有服務(wù)的檢查赏胚。
4 server列表同步
下重點(diǎn)來了觉阅,每個nacos服務(wù)器數(shù)是怎么保證healthyList(server列表)是一樣的呢秘车?
解決的辦法仍然是心跳:
DistroMapper 初始化的時候會啟動一個ServerStatusReporter
ServerStatusReporter 會向其他的nacos服務(wù)器發(fā)送心跳叮趴,證明自己是健康的
ServerStatusReporter的run方法的finally會繼續(xù)調(diào)用自己权烧,這樣就相當(dāng)于是個定時任務(wù)了。
實(shí)際調(diào)用的接口是 /api/serverStatus搔驼,收到請求的nacos服務(wù)器就會更新自己的healthyList侈询。