老闆讓我重構項目,我想首先應該服務治理—eureka服務治理深入淺出
分散式是現在互聯網架構的首選。在分散式中我們會有三方理論簡稱CAP
簡稱 | 全稱 | 解釋 |
---|---|---|
C | Consistency | 數據一致性 |
A | Availability | 可用性,性能 |
P | Partition tolerance | 分區容錯性 |
> 今天我們就來看看分散式中關於服務治理這塊的服務
什麼是服務治理
-
在多個服務之間相互調用的時候比較零散,管理起來比較麻煩。當被調用者有所改動可能都會牽扯到調用者的修改。所以服務治理應運而生。
-
spring cloud的Eureka實現了服務註冊、服務調用、負載均衡、容錯。這也是服務治理模組通用功能。
-
服務註冊和服務調用在eureka看來都是客戶端。eureka服務是服務端。所以他是一種典型的CS架構。eureka客戶端需要與eureka服務保持心跳機制。這樣eureka服務才會認為客戶端沒有宕機。
- 上述的架構圖可以清楚的看出,eureka服務端可集群化,服務提供者可以集群化。客戶端就沒必要集群化。就算集群化對於eureka服務來說也是單機的consumer。
Eureka調用過程
-
service provider啟動時會將自己服務的資訊封裝後註冊到eureka註冊中心上。service consumer已provider註冊名去註冊中心尋找到真實地址並進行調用。
-
針對service provider的管理對於service consumer來說不需要知道service provider的具體資訊。只需要知道service provider的註冊名就行了。在我們集群化後也不用擔心provider我們具體的調用地址。負載均衡也是eureka幫我分配了。我們客戶端只負責介面的調用。
Eureka單機註冊
Eureka 單機啟動
- 這裡我們不做spring其他的解釋,詳細請看git分支詳細程式碼
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-starter-netflix-eureka-server</artifactid>
</dependency>
-
在我們新建的項目中pom文件中新增如上gva。就會將eureka服務端功能注入。下面我們只需要添加一些配置啟動就行了。
-
添加依賴後我們在springboot項目中yml中添加如下配置
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false #表示該模組作為eureka服務,自己是不需要想自己註冊的,註冊了只是徒增煩惱
fetch-registry: false # 表示自己就是註冊中心。自己是管理者不是被管理者。
service-url:
defaultZone: //${eureka.instance.hostname}:${server.port}/eureka/
- 最後我們在spiringboot啟動類上開啟eurekaserver就行了。
@EnableEurekaServer
- 能夠訪問說明我們的eureka服務正常啟動。現在沒有客戶端註冊上來。所以現在看到DS Replicas列表是空的。
單機註冊
-
上面我們已經單機啟動了eureka服務。下面我們看看服務註冊是否可以。我們已之前payment模組為例。
-
pom中添加client坐標
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-starter-netflix-eureka-client</artifactid>
</dependency>
- yml中填入地址
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: //localhost:7001/eureka
- 主啟動類上添加註解
@EnableEurekaClient
集群註冊
-
現在我們多開幾個payment進行註冊
-
因為我們是在idea中開發的。還沒有打成jar包。也是為了方便調試這裡通過idea直接複製的payment項目
- 現在我們看看我們本地idea啟動項目的情況 , payment已經有兩個了分別是8001,8002
- 現在我們看到eureka服務上也出現了8001,8002了
客戶調用
-
還記得我們的feature/cloud-pre上order模組是如何調用payment的嗎。是的我們通過resetTemplate進行http方式調用的。現在我們還是通過他進行調用只不過調用地址是payment註冊在eureka上的服務名。
-
這裡客戶端如何註冊和payment配置一樣的。因為雖然是order調用payment,但是對於eureka來說payment和order都是客戶端。所以配置都是一樣的。
- 現在在單機的eureka上我們看到了單機的order服務和集群的payment服務。下面我們order調用payment的地方做如下修改
- 只是調用跟地址進行了修改。當然前提是restTemplate支援了負載均衡。
- 下面結果如何讀者可以自行測試了。
//localhost/order/getpayment/123
針對這個介面調用多次。會發現返回結果里的服務埠會不斷的8001,8002切換。因為restTemplate默認是輪詢的。而我們這裡payment提供了兩個服務。到這裡我們就實現了eureka單機版的服務註冊及調用
Eureka集群註冊
- 上面是單機的eurake。下面我們看看eurake集群如何配置。對於eureka客戶端來說註冊到eureka集群上來說非常簡單。
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: //localhost:7001/eureka,//www.eureka2/eureka
-
像上述一樣defaultZone後面直接追加eureka服務就行了。正常集群都是布置在不同機器上的。所以域名或者ip都是不同的。如果讀者在一台機器上部署可以通過nginx將不同服務分配到不同域名下。因為在eureka服務端上配置需要用到域名。
-
客戶端是直接追加。eureka服務端改動也不是很多只需要將hostname配置唯一就行了。
eureka:
instance:
hostname: www.zxhtom1.com #eureka服務端的實例名字
client:
register-with-eureka: false #表識不向註冊中心註冊自己
fetch-registry: false #表示自己就是註冊中心,職責是維護服務實例,並不需要去檢索服務
service-url:
defaultZone: //eureka7002.com:7002/eureka/
- 所以說如果是單機部署集群,我們就需要通過nginx轉發下。這裡不贅述
idea 如何同一個項目啟動多次
- 剛才在部署集群的時候為了方便演示。我們藉助idea啟動多個實例。在裡面分配不同的埠。但是在部署eureka集群是就沒法搞了。因為需要改變配置文件內容。我們可以在啟動的時候指定外部配置文件
Eureka自我保護
為什麼要自我保護
- 上面我們發現有兩個8002的payment。為什麼會出現如此奇怪的問題呢。排查發現一開始我通過idea啟動了8001,8002。然後我又通過引入外部配置文件的方式重新啟動了8002。這個時候原來的8002實例其實已經掛了。這個時候eureka會認為出現50%的客戶端沒有準時發送心跳。50<85 這個時候eureka認為大批客戶端可能因為網路波動導致沒有及時回復。eureka會開啟自我保護機制。
- 雖然上面是個反面列子。也恰恰說明了為什麼需要自我保護。加入這個時候8002在其他機器上因為網路延遲被踢出就會出現冤假錯案。所以這也解釋了為什麼上述出現兩個8002.
如何開啟自我保護
- 自我保護的功能是默認開啟的。
eureka.server.enable-self-preservation: false
我們通過此屬性設置false就是關閉自我保護。
自我保護如何激活
-
其實上面兩個8002是一種意外。我們無意中觸發了自我保護。
-
自我保護機制條件 : 最近一分鐘收到心跳數執行緒占匯流排程85%以下。
-
低於85%說明沒有指定活躍數進行心跳回復,所以認為是網路波動了。
-
自我保護的臨界值= renews(last min)/renews(threshold)
-
通過計算我們知道是75% 。 如果不算上正常的8002 。 那就是50% 。 所以不管怎麼樣都會觸發自我保護的。
-
自我保護也滿足的開篇提到的CAP原理中的A理論。eureka滿足了高可用性原則。及時客戶端真的宕機了也要留下。寧可多留也不錯殺。這樣就會導致數據不一致的情況。