Eureka的自我保護與健康檢查機制
Eureka的自我保護
Eureka的自我保護是默認開啟的如果需要關(guān)閉需要加上相關(guān)的配置谍失。
#YAML配置
eureka:
server:
evictionIntervalTimerInMs: 30000 #每間隔30秒剔除一次下線的服務(wù)
enableSelfPreservation: false #關(guān)閉Eureka的自我保護
Eureka的自我保護機制其實是為了在網(wǎng)絡(luò)狀況不穩(wěn)定的情況下仍然能在一段時間內(nèi)保存服務(wù)的地址信息捶障,防止微服務(wù)因網(wǎng)絡(luò)原因頻繁被剔除和注冊铃拇,出現(xiàn)短時間內(nèi)頻繁修改注冊信息的問題加派,也防止Eureka對服務(wù)狀態(tài)的誤判熟尉。
當(dāng)Eureka進入自我保護狀態(tài)時,Eureka頁面會出現(xiàn)紅色的提示標語熙卡。
EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.
實際上杖刷,我們大部分情況下會注意到這個服務(wù)明明停掉了,為什么狀態(tài)還會是UP驳癌?網(wǎng)上大部分都是一筆帶過滑燃,都是粗暴的剔除下線服務(wù),就是上面提到的直接關(guān)閉自我保護颓鲜。在微服務(wù)本地的配置里配合Eureka加上這個:
eureka:
instance:
# 每間隔30s表窘,向服務(wù)端發(fā)送一次心跳,證明自己依然"存活"
lease-renewal-interval-in-seconds: 15
# 告訴服務(wù)端甜滨,如果我60s之內(nèi)沒有給你發(fā)心跳乐严,就代表我"死"了,將我踢出掉衣摩。
lease-expiration-duration-in-seconds: 30
的確解決了不會再輪訓(xùn)到下線的服務(wù)了昂验,可我就是想見見Eureka服務(wù)狀態(tài)里面的DOWN、OUT_OF_SERVICE艾扮、UNKNOWN的這些狀態(tài)值既琴。那么這個健康狀態(tài)對于Eureka來說誰健康與否的判決別人說的不算,自家人知道自家事泡嘴,就統(tǒng)一交給微服務(wù)自己解決甫恩,真的是好有道理。
Eureka的健康檢查
客戶端需要在工程中添加組件依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>1.5.14.RELEASE</version>
</dependency>
然后在配置文件里面加上健康狀態(tài)檢查配置:
eureka:
client:
healthcheck:
enabled: true
這時酌予,啟動自己的服務(wù)磺箕,通過http://localhost:port/health訪問就可以得到服務(wù)的健康狀態(tài)信息:
{"description":"Composite Discovery Client","status":"UP"}
當(dāng)這個配置設(shè)置為false時,服務(wù)將不會把健康狀態(tài)傳遞給Eureka抛虫,那么Eureka就不會再更新Status信息滞磺,但是此時仍能夠通過上面的地址獲取這個真實的狀態(tài)信息。
這個信息是怎么來的呢莱褒?
當(dāng)直接增加配置啟動項目時击困,項目啟動會報找不到HealthAggregator類的錯誤,那么可以確定Eureka的服務(wù)的健康信息是由這個類來生成的广凸,在根據(jù)配置的eureka.client.healthcheck.enabled在代碼中查找阅茶,可以找到一個注解:
@ConditionalOnProperty(value = "eureka.client.healthcheck.enabled", matchIfMissing = false)
,默認情況下谅海,健康狀態(tài)檢查接口是關(guān)閉的脸哀,當(dāng)關(guān)閉時對EurekaHealthCheckHandler這個Bean的創(chuàng)建沒有關(guān)系,/health這個url仍然能夠訪問服務(wù)扭吁,返回狀態(tài)為UP的JSON字符串撞蜂。
被注解這個類是一個內(nèi)部類:
@Configuration
@ConditionalOnProperty(value = "eureka.client.healthcheck.enabled", matchIfMissing = false)
protected static class EurekaHealthCheckHandlerConfiguration {
@Autowired(required = false)
private HealthAggregator healthAggregator
= new OrderedHealthAggregator();
@Bean
@ConditionalOnMissingBean(HealthCheckHandler.class)
public EurekaHealthCheckHandler eurekaHealthCheckHandler() {
return new EurekaHealthCheckHandler(this.healthAggregator);
}
}
可以看出當(dāng)用戶自己沒有創(chuàng)建HealthCheckHandler這個Bean時盲镶,會自己創(chuàng)建一個默認的健康狀態(tài)檢查的類,那么Eureka注冊中心就是通過客戶端的/health來獲取服務(wù)的健康狀態(tài)的蝌诡,也就是說只有在微服務(wù)自己實現(xiàn)了HealthCheckHandler這個接口并且創(chuàng)建Bean之后溉贿,Eureka中status狀態(tài)才會有變化。這個可以通過下面這個類得到印證:
org.springframework.boot.actuate.health.Status
這個類中定義了服務(wù)狀態(tài)的UNKNOWN,UP,DOWN,OUT_OF_SERVICE這四個狀態(tài)浦旱,Eureka中的Status顯示的四個狀態(tài)剛好可以對上宇色。
總結(jié)
這兩個應(yīng)該是相互配合使用的。
Eureka的自我保護是對微服務(wù)實例的地址信息進行保護颁湖,避免因一些意外情況將正常節(jié)點直接剔除宣蠕。
實例的健康檢查則是微服務(wù)與Eureka注冊中心交互正常的情況下,微服務(wù)因自己內(nèi)部原因無法正常對外提供服務(wù)甥捺,主動告訴注冊中心自己出了問題抢蚀,讓注冊中心別發(fā)新的請求過來。
Eureka使用中镰禾,兩種方式無論哪一種單獨使用都有其局限性思币,所以在正常生產(chǎn)環(huán)境下,肯定需要自己針對業(yè)務(wù)場景調(diào)整配置參數(shù)來實現(xiàn)服務(wù)的高可用羡微。