1. 程式人生 > >《Spring Cloud》學習(一) 服務治理!

《Spring Cloud》學習(一) 服務治理!

  前言:之前網上學習過Spring Cloud,對於工作上需要是足夠了,總歸對於一些方面一知半解,最近難得有些閒暇時間,有幸讀了崔永超先生的《Spring Cloud 微服務實戰》,一方面記錄下自己的學習歷程和讀後感,一方面分享下自己對Spring Cloud微服務的一些見解,寫下此文。
  注意:本文著重於描述Spring Cloud執行的機制和原理部分,不會涉及到過多的程式碼,不會演示如何搭建註冊發現,高效能註冊中心,配置負載均衡等等,但是會對其內部執行機制及原理進行一定的詳解。所以本文預設讀者有一定的Spring Cloud基礎。您如果打算系統學習該技術,本人還是推薦上述提及書籍。

  當然歡迎大牛指導錯誤及不足!

 


 

  介紹:Spring Cloud是基於Spring Boot實現的微服務架構工具,提供了配置管理,服務治理,斷路器,智慧路由,微代理,控制匯流排,全域性鎖,決策競爭,分散式會話,集權狀態管理等操作。

 

    第一章 服務治理

 

  服務治理是微服務架構的核心與基礎,主要實現各個服務例項的自動化註冊與發現。Spring Cloud Eureka基於 Netflix Eureka 做了二次封裝,主要負責完成微服務架構中的服務治理功能。主要用來實現服務註冊發現,同時包含服務端,客戶端元件。

 

一.服務註冊 服務續約 服務發現

1.服務註冊 服務續約


  服務註冊:服務治理中,構建註冊中心來統一管理每個服務,客戶端向註冊中心傳送自身服務的服務名,埠,IP,通訊協議等等元資料資訊。註冊中心會將其並儲存至本地服務清單(雙層Map結構儲存)。

  高可用註冊中心:分散式環境中,我們需要充分考慮發生故障的情況,所以在生產環境中必須對各個元件進行高可用部署,對於服務註冊中心也一樣。需要構建高可用的服務註冊中心以增強系統的可用性。Eureka Server的設計一開始就考慮了高可用問題,在Eureka的服務治理設計中,所有節點即是服務提供方,也是服務消費方,服務註冊中心也不例外。

  Eureka Server的高可用實際上就是將自己作為服務向其他服務註冊中心註冊自己,這樣就可以形成一組互相註冊的服務註冊中心, 以實現服務清單的互相同步, 達到高可用的效果。以叢集的方式部署註冊中心,允許分片故障期間,其他分片繼續提供服務發現註冊,故障分片恢復時其他分片會把狀態同步回來。不同的註冊中心分片通過非同步方式互相複製狀態,提供高的例項可用性。

  如圖4個客戶端之間可以相互呼叫。

  

   服務續約:客戶端向註冊中心註冊自身的服務資訊後,並且週期性的(預設30秒)傳送心跳(eurekaTransport.registrationClient.sendHeartBeat方法)來更新服務租約。註冊中心如果一段時間(預設90秒)內沒收到客戶端的心跳續約,則會剔除該客戶端。

 

註冊流程詳解:

  客戶端操作:服務啟動時傳送REST請求到註冊中心的方式進行的,以discoveryClent.register(instanceinfo)方法進行服務註冊,可以看到以com.netflix.appinfo.Instanceinfo物件為引數,該物件就是註冊時客戶端給服務端的服務的元資料資訊(主機名、IP地址、埠號、狀態頁和健康檢查等等)。

  註冊中心端操作:註冊中心接收到註冊請求後,先呼叫publishEvent函式,將該新服務註冊的事件已請求轉發的方式傳播出去,通知其他節點的註冊中心,達到服務同步,然後呼叫com.netflix.eureka.registry.AbstractlnstanceRegistry父類中的register註冊實現,將InstanceInfo中的元資料資訊儲存在一個ConcurrentHashMap物件中。ConcurrentHashMap<String, Map<String,Lease<InstanceInfo>>>物件,它是一個兩層Map結構,第一層的key儲存服務名:InstanceInfo中的appName屬性,第二層的key儲存例項名:InstanceInfo中的instanceId屬性。

 

2.服務發現

  服務啟動會呼叫com.netflix.discovery.DiscoveryClient的initScheduledTasks函式,發現在其中還有兩個定時任務,分別是 服務獲取 和 服務續約。

  當我們啟動服務消費者的時候,它會發送一個REST請求給服務註冊中心,來獲取註冊中心儲存的服務清單。為了效能考慮,Eureka Server會維護一份只讀的服務清單來返回給客戶端,同時每個客戶端都會週期的(預設30秒)向註冊中心諮詢,獲取到所有的服務例項清單,存入本地(serverList),可以對其他具體服務例項進行訪問。(若希望修改快取清單的 更新時間,可以通過 eureka.clent.registry-fetch-interval-seconds=30引數進行修改)。


二.服務消費


  服務消費者在獲取服務清單後,通過服務名可以獲得具體提供服務的例項名和該例項的元資料資訊。因為有這些服務例項的詳細資訊,所以客戶端可以根據自己的需要決定具體呼叫哪個例項(使用RestTemplate)。

  RestTemplate:主要有GET,POST,PUT,DELETE的請求方式。

  GET有getForEntity和getForObject的過載。POST有postForEntity和postForObject的過載。

   一般我們都會使用負載均衡結合Ribbon完成。當Ribbon與Eureka聯合使用時,Ribbon的服務例項清單RibbonServerList會被DiscoveryEnabledNIWSServerList重寫,擴充套件成從Eureka註冊中心中獲取服務端列表。Ribbon是一個基於HTTP和TCP的客戶端負載均衡器,它可以在通過客戶端中配置的ribbonServerList服務端列表去輪詢訪問(預設)以達到均衡負載的作用。

  (具體的Ribbon及RestTemplate下章負載均衡會詳解)

 

三.服務下線 失效剔除

 

  3.1服務下線

  在系統執行過程中必然會面臨關閉或重啟服務的某個例項的情況,在服務關閉期間,我們自然不希望客戶端會繼續呼叫關閉了的例項。 所以在客戶端程式中,當服務例項進行正常的關閉操作時,它會觸發一個服務下線的REST請求給註冊中心,告訴服務註冊中心:我要下線了。註冊中心在接收到請求之後,將該服務狀態置為下線(DOWN), 並把該下線事件傳播出去。

  

  3.2失效剔除

  有些時候,我們的服務例項並不一定會正常下線,可能由於記憶體溢位,網路故障等原因使得服務不能正常工作,而服務註冊中心並未收到服務下線的請求。為了從服務列表中將這些無法提供服務的例項剔除,註冊中心在啟動的時候會建立一個定時任務,預設每隔一段時間(預設為60秒)將當前清單中超時(預設為90秒)沒有續約的服務剔除出去。

 

  3.3自我保護

  自我保護機制:服務註冊到Eureka Server之後,會維護一個心跳連線,告訴Eureka Server自己還活著。EurekaServer在執行期間,會統計心跳失敗的比例在15分鐘之內是否低於85%, 如果出現低於的情況,EurekaServer會將當前的例項註冊資訊保護起來,讓這些例項不會過期,儘可能保護這些註冊資訊。但是在這段保護期間內例項若出現問題,那麼客戶端很容易拿到實際已經不存在的服務例項,會出現呼叫失敗的清況,所以客戶端必須要有容錯機制,比如可以使用請求重試、斷路器等機制。

  如果Eureka以叢集模式部署,當叢集中有分片出現故障時,那麼Eureka就轉入自我保護模式。它允許在分片故障期間繼續提供服務的發現和註冊,當故障分片恢復執行時,叢集中的其他分片會把它們的狀態再次同步回來。

  當然也可以使用eureka.server.enableself-preservation=false引數來關閉保護機制,以確保註冊中心可以將不可用的例項正確剔除。


四.健康檢測

  Actuator監控管理:為了系統獲取各個微服務相關指標比如環境變數,垃圾收集資訊,記憶體資訊,執行緒池資訊,HTTP請求統計。Spring Cloud提供了Actuator模組來自動構建一系列用於監控的端點,並且支援擴充套件。模組中自帶一些常用資源的健康指標檢介面,比如磁碟空間,DataSource連結,Mongo資料庫可用,Rabbit服務,Redis,Solr檢測等,也可以自己實現自定義檢測器。
  預設情況下,Eureka中各個服務例項的健康檢測並不是通過spring-boot-actuator模組的/health 端點來實現的, 而是依靠客戶端心跳的方式來保持服務例項的存活。在Eureka 的服務續約與剔除機制下,客戶端的健康狀態從註冊到註冊中心開始都會處於 UP狀態, 除非心跳終止一段時間之後,服務註冊中心將其剔除。 預設的心跳實現方式可以有效檢查客戶端程序是否正常運作, 但卻無法保證客戶端應用能夠正常提供服務。由於大多數微服務應用都會有一些其他的外部資源依賴,比如資料庫、 快取、 訊息代理等,如果我們的應用與這些外部資源無法聯通的時候, 實際上已經不能提供正常的對外服務了,但是因為客戶端心跳依然在執行, 所以它還是會被服務消費者呼叫,而這樣的呼叫實際上並不能獲得預期的結果。
  在Spring Cloud Eureka中,我們可以通過簡單的配置,把Eureka客戶端的健康檢測交給spring-boot-actuator模組的/health端點, 以實現更加全面的健康狀態維護。

 


 

本文連結:《Spring Cloud》學習(一) 服務治理!
轉載宣告:本部落格由靜影殘月創作。可自由轉載、引用,但需署名作者且註明文章出