注:此隨筆爲讀書筆記。《Spring Cloud微服務實戰》,想學習Spring Cloud的同伴們能夠去看看此書,裏面對源碼有詳細的解讀。緩存
上篇主要介紹了什麼是微服務以及微服務治理的簡單實現,如微服務註冊中心的實現、微服務註冊的實現、微服務的發現和消費的實現、微服務註冊高可用的實現。本篇主要介紹一下微服務治理機制。服務治理基礎架構有是三個核心要素:服務註冊中心、服務提供者、服務消費者,服務提供者通常執行服務註冊、服務同步、服務續約任務,服務消費者會執行獲取服務、服務調用、服務下線任務,服務註冊中心會執行失效剔除、自我保護任務。下面一一理解。網絡
場景:架構
有兩個服務註冊中心,互相註冊組成高可用集羣;負載均衡
服務提供者啓動兩個實例,一個註冊在註冊中心1中,一個註冊在註冊中心2中;(疑問:這裏我試了,服務只指向一個註冊中心,只啓動一個實例,兩個註冊中心都會有剛啓動的服務,這應該也算服務同步吧)微服務
有兩個服務消費者,一個指向註冊中心1中,一個指向註冊中心2中。性能
服務提供者在啓動的時候會發送REST請求將本身註冊到註冊中心,同時帶上了自身服務的一些元數據信息。註冊中心接收到請求後,將元數據信息存儲在一個雙層結構Map中,其中第一層的Key是服務名,第二層的Key是具體服務的實例名。如Ribbon負載均衡的例子中,一個服務有多個實例的狀況。學習
因爲服務註冊中心之間互相註冊爲服務,當服務提供者發送註冊請求到其中一個註冊中心時,它會將請求轉發給集羣中相連的其餘註冊中心,此時集羣中全部的註冊中心都會註冊該服務實例,從而實現註冊中心之間的服務同步。經過服務同步,消費者就能夠經過這兩個註冊中心的任意一個獲取到兩個服務提供者的服務信息。fetch
解釋:哪些服務是被服務A同步的呢?spa
即各個註冊中心中和服務A的服務名、端口號都相同的服務。debug
註冊中心1:
註冊中心2:
在服務註冊完以後,服務提供者會維護一個心跳來告訴註冊中心本身還活着,以防止註冊中心的「剔除任務」將該服務實例從服務列表剔除,咱們把該操做稱爲續約。
eureka.instance.lease-renewal-interval-in-seconds=30 #服務續約任務的調用間隔時間,默認爲30秒
eureka.instance.lease-expiration-duration-in-seconds=90 #定義服務失效的時間,默認90秒
到這裏,服務註冊中心都註冊了一個服務,而且該服務都擁有兩個服務實例。當咱們啓動服務消費者的時候,會發送REST請求給註冊中心,來獲取註冊中心的服務清單。爲了性能考慮,註冊中心會維護一份只讀的服務清單返回給客戶端,該緩存清單默認30秒更新一次。
eureka.client.fetch-register=true #肯定會獲取註冊中心的服務清單
eureka.client.fetch-register-interval-seconds=30 #緩存清單的更新時間,默認30秒
服務消費者獲取到服務清單後,經過服務名能夠得到服務提供的服務實例名和該實例的元數據信息,因爲服務實例有詳細的元數據信息,於是客戶端能夠根據本身的須要調用哪一個服務實例,在Spring Cloud Ribbon中採用輪詢的方式進行調用,從而實現客戶端的負載均衡。
當服務掛掉後,會觸發下線的REST請求給註冊中心,註冊中心收到請求後會將該服務的狀態設置成「DOWN」,並把下線事件傳播出去。
有些時候咱們的服務不會正常下線,有多是內存溢出、網絡故障等緣由致使服務不可用,而註冊中心並外收到服務下線請求。爲了從服務列表中將沒法提供的服務正確剔除,註冊中心在啓動的時候會建立一個定時任務,每隔一段時間(默認60秒)將當前服務清單中超時(默認90秒)沒有續約的服務剔除。
服務註冊到註冊中心後,會維護一個心跳鏈接,告訴註冊中心本身還活着。註冊中心在運行期間,會統計該服務心跳失敗的比例,15分鐘低於85%(在開發環境,debug調試的時候很容易出現;生成環境網絡不穩定會致使) 的狀況下,註冊中心會將服務信息保存起來,讓這些服務實例不會過時,更不會剔除服務實例。可是這段時間服務實例若出現問題,那麼消費者很容易拿到不可用的服務實例,從而出現調用失敗的狀況。因此客戶端須要有容錯機制,好比使用請求重試、斷路由等機制。
咱們公司內部產品遇到過這種狀況,用戶登陸系統時有時候超時最終返回錯誤頁面,有時候就能夠正常登陸。當時肯定的影響因素是網絡很是不穩定,那麼在網絡穩定性問題解決以前,服務須要正常訪問,當時採用的方案是請求重試機制,通常在第二次請求時便會請求成功,並且速度和網絡良好的狀況差很少。qa那邊也會認爲這個問題解決了。固然,網絡正常後,服務也會正常訪問。如今看來,原來是註冊中心的自我保護機制致使的。解決方案就是請求重試和斷路由等機制了。
因爲在本地開發的時候,debug調試,會常常引發註冊中心自我保護機制,因此,在本地開發的時候能夠關閉註冊中心的自我保護機制,以確保註冊中心將不可用的服務當即剔除。
eureka.server.enable-self-preservation=false #關閉自我保護機制