Eureka, Client, Ribbon之間的緩存和服務實時上下線實現思路分析

在使用Eureka做註冊中心時,我平時遇到的最不爽問題,就是無法做到實時上下線。比如,我服務已經正常下線了,爲什麼上游還能調通?我服務已經上線了,爲什麼還有等"很久"才能真正被其他服務所"發現"?其實這些都是從Eureka到Client再到Ribbion這條鏈路中的逐級緩存造成的。

Eureka爲什麼要使用緩存

比如,對於Eureka來說,Eureka Client獲取註冊更新信息時,Eureka Server返回的數據其實是從一個默認每30s才更新的緩存獲取的。也就是說,如果你服務下了一個,即使client是在服務下線之後發請求查詢的註冊列表,那這次請求也不會包括服務下線的信息。那麼Eureka爲什麼要搞cache而不是實時的返回註冊信息呢?我個人推測了一下,應該是爲了在訪問註冊數據結構時儘量少加鎖,從而提升單次請求時的性能。如果沒有這層cache, 那麼對於服務註冊表這個數據結構來說,就會存在併發讀寫的情況,那就避免不了加鎖保護。如果有cache, 是可以做到完全不加鎖的。想一下,對於微服務架構來說,特點就是每個服務較輕,但服務數量較多。如果每個服務都定時請求eureka更新註冊信息的話,對於Eureka Server來說,確實是可能會造成嚴重的鎖競爭的。除了這個responseCache外,Eureka對於無心跳服務的清理也是默認每60s執行一次的,也就是說對於異常下線的服務(沒有主動取消註冊,而是中斷了心跳),在Eureka Server端最大會有長達 60s + 30s * 3 = 150s的延遲。這裏的30s * 3 是3個心跳的週期。

Eureka Client的緩存

Eureka Client默認會對註冊信息做30s緩存 ,這個很好理解 ,因爲我們當然不希望每次RPC都要重新查一次註冊表,這是很浪費的。 這是常規操作,無可厚非。

Ribbon的緩存

這就有點詭異了。Ribbon向上對接Eureka Client, 向下對接實現發起HTTP請求的客戶端。ribbon自身也是有30s緩存的,即ribbon會每30s向Eureka Client那裏索要註冊信息,注意是Eureka Client而不是Eureka Server,這樣就更加劇了整個系統對服務上下線感知的延遲。我認爲Ribbon這樣設計,原因是考慮到了其上游不僅僅是Eureka Client, 還可能是配置文件,或者以編程的方式輸入的註冊列表,而這些查詢是有可能比較耗時的。Ribbon爲了兼容這些情況,不得不添加了緩存。

實時上下線思路

只能用消息中間件了。新做一個上下線管理服務,提供HTTP接口來上下線指定服務,當指定要下線A服務時,先向Eureka發請求,將此服務下所有的實例都刪掉,然後再向kafka類似這樣的消息系統中發一條消息,所有的微服務都要監聽此消息隊列。
服務收到下線消息時,將指定服務從本地Ribbon服務列表中刪除。這裏Ribbon的 Loadbalancer提供了markServerDown()方法可以使用,還是容易實現的。
服務收到上線消息時,需要將服務信息添加到Ribbon中,Ribbon雖然也提供了對應的方法,但是參數較爲複雜,還需要研究一下。
這些功能可以直接打包成starter, 寫好以後各服務直接引用即可。

其實我更希望Eureka官方能出一套解決實時性的方案,然並卵,Eureka已經不維護了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章