玩轉SpringCloud專題(六)-SpringCloud註冊中心Eureka詳解

1.服務提供者

服務提供者要向EurekaServer註冊服務,並且完成服務續約等工作。
在這裏插入圖片描述

服務註冊

服務提供者在啓動時,會檢測配置屬性中的:eureka.client.register-with-erueka=true參數是否正確,事實上默認就是true。如果值確實爲true,則會向EurekaServer發起一個Rest請求,並攜帶自己的元數據信息,Eureka Server會把這些信息保存到一個雙層Map結構中。第一層Map的Key就是服務名稱,第二層Map的key是服務的實例id。

服務續約

在註冊服務完成以後,服務提供者會維持一個心跳(定時向EurekaServer發起Rest請求),告訴EurekaServer:“我還活着”。這個我們稱爲服務的續約(renew);

有兩個重要參數可以修改服務續約的行爲:

eureka:
  instance:
    lease-expiration-duration-in-seconds: 90
    lease-renewal-interval-in-seconds: 30
  • lease-renewal-interval-in-seconds:服務續約(renew)的間隔,默認爲30秒
  • lease-expiration-duration-in-seconds:服務失效時間,默認值90秒

也就是說,默認情況下每個30秒服務會向註冊中心發送一次心跳,證明自己還活着。如果超過90秒沒有發送心跳,EurekaServer就會認爲該服務宕機,會從服務列表中移除,這兩個值在生產環境不要修改,默認即可。

但是在開發時,這個值有點太長了,經常我們關掉一個服務,會發現Eureka依然認爲服務在活着。所以我們在開發階段可以適當調小。

eureka:
  instance:
    lease-expiration-duration-in-seconds: 10 # 10秒即過期
    lease-renewal-interval-in-seconds: 5 # 5秒一次心跳

實例id

先來看一下服務狀態信息:

在Eureka監控頁面,查看服務註冊信息:

實例id

先來看一下服務狀態信息:

在Eureka監控頁面,查看服務註冊信息:

在這裏插入圖片描述

在status一列中,顯示以下信息:

  • UP(1):代表現在是啓動了1個示例,沒有集羣
  • DESKTOP-2MVEC12:user-service:8081:是示例的名稱(instance-id),
    • 默認格式是:${hostname} + ${spring.application.name} + ${server.port}
    • instance-id是區分同一服務的不同實例的唯一標準,因此不能重複。

我們可以通過instance-id屬性來修改它的構成:

eureka:
  instance:
    instance-id: ${spring.application.name}:${server.port}

重啓服務再試試看:
在這裏插入圖片描述
在status一列中,顯示以下信息:

  • UP(1):代表現在是啓動了1個示例,沒有集羣
  • localhost:springcloud-demo-service:80:是示例的名稱(instance-id),
    • 默認格式是:${hostname} + ${spring.application.name} + ${server.port}
    • instance-id是區分同一服務的不同實例的唯一標準,因此不能重複。

我們可以通過instance-id屬性來修改它的構成:

eureka:
  instance:
    instance-id: ${spring.application.name}:${server.port}

重啓服務再試試看:
在這裏插入圖片描述

2.服務消費者

獲取服務列表

當服務消費者啓動是,會檢測eureka.client.fetch-registry=true參數的值,如果爲true,則會從Eureka Server服務的列表只讀備份,然後緩存在本地。並且每隔30秒會重新獲取並更新數據。我們可以通過下面的參數來修改:

eureka:
  client:
    registry-fetch-interval-seconds: 5

生產環境中,我們不需要修改這個值。
但是爲了開發環境下,能夠快速得到服務的最新狀態,我們可以將其設置小一點。

3.失效剔除

失效剔除

有些時候,我們的服務提供方並不一定會正常下線,可能因爲內存溢出、網絡故障等原因導致服務無法正常工作。Eureka Server需要將這樣的服務剔除出服務列表。因此它會開啓一個定時任務,每隔60秒對所有失效的服務進行剔除。

可以通過eureka.server.eviction-interval-timer-in-ms參數對其進行修改,單位是毫秒,生產環境不要修改。

這個會對我們開發帶來極大的不變,你對服務重啓,隔了60秒Eureka才反應過來。開發階段可以適當調整,比如10S

4.自我保護

我們關停一個服務,就會在Eureka面板看到一條警告:
在這裏插入圖片描述

4.1.自我保護的條件

一般情況下,微服務在 Eureka 上註冊後,會每 30 秒發送心跳包,Eureka 通過心跳來判斷服務時候健康,同時會定期刪除超過 90 秒沒有發送心跳服務。

有兩種情況會導致 Eureka Server 收不到微服務的心跳

a.是微服務自身的原因
b.是微服務與 Eureka 之間的網絡故障

通常(微服務的自身的故障關閉)只會導致個別服務出現故障,一般不會出現大面積故障,而(網絡故障)通常會導致 Eureka Server 在短時間內無法收到大批心跳。考慮到這個區別,Eureka 設置了一個閥值,當判斷掛掉的服務的數量超過閥值時,Eureka Server 認爲很大程度上出現了網絡故障,將不再刪除心跳過期的服務。

那麼這個閥值是多少呢?

15 分鐘之內是否低於 85%;Eureka Server 在運行期間,會統計心跳失敗的比例在 15 分鐘內是否低於 85%,這種算法叫做 Eureka Server 的自我保護模式。

4.2.爲什麼要自我保護

因爲同時保留"好數據"與"壞數據"總比丟掉任何數據要更好,當網絡故障恢復後,這個 Eureka 節點會退出"自我保護模式"。

當一個服務未按時進行心跳續約時,Eureka會統計最近15分鐘心跳失敗的服務實例的比例是否超過了85%。在生產環境下,因爲網絡延遲等原因,心跳失敗實例的比例很有可能超標,但是此時就把服務剔除列表並不妥當,因爲服務可能沒有宕機。Eureka就會把當前實例的註冊信息保護起來,不予剔除。生產環境下這很有效,保證了大多數服務依然可用。

4.3.如何關閉自我保護

但是這給我們的開發帶來了麻煩, 因此開發階段我們都會關閉自我保護模式:
修改 Eureka Server 配置文件

eureka:
  server:
    enable-self-preservation: false # 關閉自我保護模式(缺省爲打開)
    eviction-interval-timer-in-ms: 1000 # 掃描失效服務的間隔時間(缺省爲60*1000ms)
#關閉自我保護:true 爲開啓自我保護,false 爲關閉自我保護
eureka.server.enableSelfPreservation=false
#清理間隔(單位:毫秒,默認是 60*1000)
eureka.server.eviction.interval-timer-in-ms=1000

然後啓動server和服務,觀察關閉服務前後的變化
在這裏插入圖片描述
上面有提示自我保護已經關閉,測試關閉provider服務
在這裏插入圖片描述
可以看到並沒有開啓自我保護模式!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章