服務發現之eureka

 

1、什麼是服務發現?

問題:數據庫

咱們如今有多少個服務?緩存

服務愈來愈多時,服務 URL 配置管理變得很是亂服務器

服務對外的地址變了,其餘全部有使用到的服務都要改地址網絡

增長服務,增長服務實例等,都要作運維工做session

 

1.1服務端發現模式

 

客戶端經過服務端的負載或路由訪問目標服務。架構

服務端負責負載和轉發請求,自身或者經過第三方工具,自動發現新的服務實例,並定時檢測心跳維護註冊表。負載均衡

優勢:
      服務發現功能對於客戶端而言是透明的
缺點:
      增長了一次轉發,集中式的作法沒有去中心化運維

提問:
      1.nignx/F5有服務地址列表,也有負載均衡功能,屬於服務端發現嗎?
      主要缺了「發現」功能,服務實例動態增減並不能主動識別微服務

      2.服務實例本身往服務端發送註冊請求不能夠嗎?
      服務實例是服務提供者,也多是服務消費者;若是往註冊中心發送註冊請求,那麼也能夠從註冊中心拉註冊表,這樣直接作客戶端發現不是更好?工具

 

1.2客戶端發現模式

 

客戶端自身就能夠肯定服務提供者的可用實例地址列表和使用負載均衡策略。

服務提供者向註冊中心發送註冊和心跳。
服務端只負責維護註冊表,並對外提供服務。

優勢:
      客戶端能夠靈活、智能地制定負載均衡策略
      去中心化
缺點:
      客戶端與註冊中心耦合,須要實現與註冊中心交互的代碼

 

2、服務發現的關鍵角色提取

服務提供者:
      向註冊中心發送請求,發送信息
服務消費者:
      向註冊中心發送請求,獲取信息
註冊中心:
      提供接口給服務發現客戶端調用
      維護服務實例信息集合
      集羣之間信息同步

 

  

3、關鍵角色要幹些什麼事情

3.1服務提供者

服務提供者:向註冊中心發送請求,發送信息

 

 

1.發送請求問題:

發送請求的工具用什麼,okhttp、resttemplate?
請求失敗怎麼辦,要重試嗎?重試的策略是什麼?

2.註冊中心地址問題:
發送信息給全部註冊中心仍是發送一個成功就好了?
註冊中心有多個的話,優先訪問哪一個呢,訪問失敗的要記錄起來下次不訪問了嗎?
地址寫在配置裏,若是有增長或調整,全部客戶端都要改?

3.發送註冊/心跳問題:
註冊和心跳調同一個接口仍是分開兩個接口比較好?
註冊後,除了要定時發送心跳,實例信息有改變的狀況下,要發給註冊中心嗎?

 

3.1.1服務提供者-發送請求問題

做爲一箇中間件如何提升可擴展性?
eureka的答案是裝飾器模式

 

 

JerseyClient:
執行rest請求的工具,eureka有RestTemplate的替換實現方案

統計信息:
根據請求類型進行統計,請求時間總計、請求失敗次數總計等

重定向:
返回的http code是302則表示要重定向(註冊中心遷移?)更換重定向的url再次發起請求,最多重定向10次

失敗重試機制:
已經請求失敗的server url記錄下來下次再也不請求;
若是失敗的url過多(好比所有都失敗的狀況,多是客戶端網絡有問題),超過閥值,則清空失敗的url記錄,把他們從新當成可用的url ,這裏要獲取註冊中心地址列表,用於重試

會話:
請求失敗的url記錄多久,永久記錄嗎?使用session機制若是20分鐘沒請求過,則重置上面的全部機制
session有效時長20分鐘左右(有隨機增減)

 

3.1.2服務提供者-註冊中心地址問題

1.發送信息給全部註冊中心仍是一個?
不論是AP仍是CP,服務提供者只需與一個註冊中心交互成功就行,服務提供者不關心註冊中心之間的數據同步

2.客戶端如何保證發送到任意一個註冊中心成功呢?
配置多個註冊中心地址,失敗了就換下一個再試

3.註冊中心地址變動問題
配置了多個註冊中心地址後,若是註冊地址有增刪改怎麼解決
將註冊中心地址放到配置中心 或 DNS txt記錄,客戶端定時去刷新獲取
(就算是存在本地配置文件,eureka也會開啓定時任務定時去取)

 

 

 

3.1.3服務提供者-發送心跳/註冊問題

註冊後,除了要定時發送心跳,實例信息有改變的狀況下,要發給註冊中心嗎?
eureka的答案是須要:
1.實例狀態變動
2.配置信息變動
LeaseExpirationDurationInSeconds 心跳有效期
LeaseRenewalIntervalInSeconds 心跳頻率
3.健康檢查處理器的增減(用於獲取實例狀態)

 

3.2服務消費者

服務消費者:向註冊中心發送請求,獲取註冊表信息

1.發送請求問題(同服務提供者)

2.註冊中心地址變動問題(同服務提供者)

3.全量仍是增量獲取應用實例信息
若是消費者本地實例信息爲空,則全量獲取,不然增量獲取,關鍵邏輯在註冊中心,這裏較簡單

 

將上面結論進行彙總

 

3.3註冊中心

註冊中心:

提供接口給服務發現客戶端調用

維護服務實例信息集合

集羣之間數據同步

3.3.1註冊中心-接口

 

如何作增量更新?

查詢是否須要緩存?

 

如何作增量更新?

eureka的答案是維護一個隊列 recentlyChangedQueue

細心的觀衆會發現,爲何接收到心跳,不會增長到recentlyChangedQueue?
隊列裏存的是引用類型,和應用實例列表是同一個地址,接收到心跳進行實例更新,定時維護最近變更實例隊列時查到實例信息變更,而後繼續將其保留在隊列裏,這樣增量查詢下次同樣能查到該實例的信息

爲何要自我保護?
若是失效的實例過多,有沒有多是註冊中心出了問題?

上一分鐘接收到心跳總數<= 實例總數*2(默認30s一次心跳) * RenewalPercentThreshold()(默認0.85)進入自我保護則不會剔除任何實例

 

3.3.2註冊中心-集羣同步

如何作集羣同步?

eureka的答案仍是維護隊列,這裏註冊、心跳、下線都會入隊,批量進行同步,失敗的加到失敗重試隊列

接收到的全部請求,都要同步嗎?

要通過過濾, 每種類型只取最新一條去同步便可

註冊中心地址變動
同服務發現客戶端同樣,定時刷新註冊中心地址,而後更新集羣節點

 

3.4架構圖

(右鍵新標籤打開可查看大圖)

 

4、結合Region和AZ(Available Zone)

區域(Region):
從設計而言,每一個 Amazon EC2 區域都與其餘 Amazon EC2 區域徹底隔離。這可實現最大程度的容錯能力和穩定性。在區域之間傳輸數據須要收費。
可用區(Availability Zone ,AZ):
若是您的實例分佈在多個可用區且其中的某個實例發生故障,則您可對您的應用程序進行相應設計,以使另外一可用區中的實例可代爲處理相關請求。可用區由區域代碼後跟一個字母標識符表示;例如,us-east-1a。

地域(Region):
不一樣地域的雲服務器 ECS、關係型數據庫 RDS、對象存儲服務 OSS 內網不互通。
不一樣地域之間的雲服務器 ECS 不能跨地域部署負載均衡,即在不一樣的地域購買的 ECS 實例不支持跨地域部署在同一負載均衡實例下。
可用區(Zone):
可用區是指在同一地域內,電力和網絡互相獨立的物理區域。同一可用區內實例之間的網絡延時更小。

理解region和az的概念後,咱們須要作什麼是否是就簡單多了?

1.服務發現客戶端,優先與相同的AZ進行通信
2.服務發現客戶端,查詢註冊中心地址列表時,只取相同region下全部AZ的註冊中心地址
2.註冊中心,也只須要將數據同步給相同region的全部AZ便可

不過屬於哪一個區,好像沒有特殊的配置吧?
eureka.client.availability-zones.us-east-1=zone2,zone1
eureka中取上面配置的第一個可用區爲優先使用的可用區

注:雖然region之間是數據隔離的,可是eureka也支持從其餘region同步信息(經過http請求)

 

常見問題探討

連連看,將以下類圖與咱們架構圖裏對象進行對應(右鍵新標籤打開可查看大圖)

eureka server 是ap仍是cp?

服務啓動後會不會立刻註冊到註冊中心?

服務提供者註冊到註冊中心後,服務消費者最快多久可以查詢到該提供者?

爲何接收心跳後不入隊,那麼更新心跳後啓不是增量查詢查不到了?

集羣同步的隊列,爲何要通過一道中轉才進行消費?

 

 

部分圖片摘自以下文章:

《聊一聊微服務架構下的服務發現模式》

相關文章
相關標籤/搜索