體系化認識微服務之四:服務註冊發現機制
作者:rhwayfun
來源:https://blog.csdn.net/u011116672
服務調用者要在衆多的微服務中調用具體的服務提供者,必然涉及到負載均衡的問題,根據負載均衡的實現可以分爲集中式LB、進程內LB和獨立進程LB。
集中式LB
LB上有所有的服務地址配置,當服務消費者調用某個服務的時候,LB會根據負載均衡策略(隨機、輪詢等)將請求轉發到具體的服務上。此外,服務調用者還需要知道LB的地址,通常的做法是運維在服務器上配置一個DNS域名或者IP,這個域名指向LB。
這種實現方式的問題每次調用都要訪問LB,LB存在單點問題,無法水平擴展
進程內LB
爲了解決每次服務調用都經過LB的不足,把LB放在客戶端可以很好解決,這裏多了一個註冊表,服務提供方啓動時,首先將服務地址註冊到服務註冊表,定期發送心跳包到服務註冊表,檢查存活狀態。
服務消費方要訪問某個服務時,經歷以下過程:
- 服務消費者在啓動時從服務註冊表獲取需要的服務註冊信息
- 將服務提供者註冊信息緩存在本地(客戶端LB)
- 監聽服務提供者註冊信息的變更,如接收到服務註冊中心的服務變更通知,則在本地緩存中更新服務的註冊信息
- 根據本地緩存中的服務註冊信息構建服務調用請求,並根據負載均衡策略(隨機負載均衡,Round-Robin負載均衡等)來轉發請求
- 對服務提供方的存活進行檢測,如果出現服務不可用的服務提供方,將從本地緩存中剔除,定期檢測本地服務註冊表的存活狀態
這一方案對服務註冊表的可用性要求很高,一般採用能滿足高可用分佈式一致的組件(例如Zookeeper、Consul、Etcd等)來實現。這裏由於LB是在服務調用者的進程內,那麼每個服務調用者都有自己的本地LB,不會導致每次調用都直接訪問LB的情況,而且服務調用者直接訪問服務提供者,沒有額外的開銷。
這樣部署的條件是服務註冊表要支持高可用,通常採用集羣部署的方式實現。目前開源組件比如Dubbo、Eureka、Karyon都是採用類似這種服務註冊發現機制,不足是要對不同的語言開發不同的客戶端,因爲LB需要進行路由,不同的語言就需要開發不同的客戶端進行路由,比如Dubbo本身是用Java開發的,只要配和註冊中心比如zookeeper就可以完成服務註冊和發現,但是使用Node.js如果要調用dubbo服務就需要開發基於Node.js的客戶端去發現dubbo的服務,相當於是Node.js版的Dubbo。
獨立進程LB
與第二種類似,區別是這將LB作爲獨立進程,好處是多語言環境下可以不用開發不同的客戶端,不足是部署複雜,增加了出錯調試的複雜度。只要LB進程的主機部署了其他應用,不管是什麼語言開發的都能通過LB完成路由,這樣就不需要開發專門的客戶端去路由了
每次服務調用都要穿透主機所在的LB,包括請求和響應。目前開源的組件有Airbnb的SmartStack