Spring Cloud Eureka 客戶(hù)端服務(wù)快速上下線(xiàn)

問(wèn)題描述

在開(kāi)發(fā)環(huán)境聯(lián)調(diào)接口過(guò)程中,出現(xiàn)bug 或 新增屬性方法 或其他需要重啟服務(wù)才能讓新代碼生效的情況,是再正常不過(guò)的事了,如果是單體應(yīng)用還好,重啟就能直接用了,但如果是Spring Cloud微服務(wù)應(yīng)用就不一樣了,因?yàn)槲覀冋{(diào)用接口都是會(huì)經(jīng)過(guò)網(wǎng)關(guān),然后網(wǎng)關(guān)再通過(guò)負(fù)載均衡將請(qǐng)求轉(zhuǎn)發(fā)后可用的服務(wù)實(shí)例,這一切很大程度上依賴(lài)于Service Discovery(服務(wù)發(fā)現(xiàn),即Spring Cloud Eureka,當(dāng)然還有其他服務(wù)發(fā)現(xiàn)框架,這里主要討論Eureka),當(dāng)服務(wù)重啟后,你會(huì)發(fā)現(xiàn)有一小段時(shí)間重新啟動(dòng)的服務(wù)變成不可用。

問(wèn)題原因

比較了解Eureka的人都知道,Eureka Server 有2個(gè)緩存,一個(gè)是可讀寫(xiě)緩存(readWriteCacheMap),另一個(gè)是只讀緩存(readCacheMap),這2個(gè)緩存存放的都是所有Eureka Client服務(wù)的服務(wù)實(shí)例列表,不過(guò)這2個(gè)Cache有不同的用途??梢院?jiǎn)單地這樣理解:

  • readWriteCacheMap: 存放的是實(shí)時(shí)的、最新的、可用的服務(wù)實(shí)例列表;服務(wù)上下線(xiàn),都會(huì)實(shí)時(shí)更新該緩存;
  • readCacheMap: 存放的是readWriteCacheMap某一時(shí)刻的拷貝,并定期(默認(rèn)是30s)從readWriteCacheMap最新的實(shí)例列表更新;

然而,Eureka ClientEureka Server請(qǐng)求獲取服務(wù)實(shí)例列表時(shí),Server端返回的是readCacheMap這個(gè)緩存里邊的內(nèi)容,所以就會(huì)出現(xiàn)請(qǐng)求的服務(wù)沒(méi)有可用的服務(wù)實(shí)例。

服務(wù)重啟后變成不可用,過(guò)段時(shí)間又變成可用的流程,具體可參考如下時(shí)序圖:


eureka 服務(wù)上下線(xiàn)

解決方案

既然知道問(wèn)題所在,只要解決思路就清晰了,無(wú)非就是縮短readWriteCacheMap緩存更新到readCacheMap中的時(shí)間,再一個(gè)是縮短Eureka Client服務(wù)從Eureka Server獲取新的服務(wù)實(shí)例列表的時(shí)間;當(dāng)然,還需要其他配置的配合,比如主動(dòng)讓不可用服務(wù)時(shí)效掉,因?yàn)?code>Spring Cloud的負(fù)載均衡默認(rèn)實(shí)現(xiàn)是Ribbon,所以還需要縮短其刷新負(fù)載列表的時(shí)間。具體配置如下:

Eureka Server

eureka:
  server:
    # 默認(rèn)30s. eureka server刷新readCacheMap的時(shí)間,注意,client讀取的是readCacheMap,
    # 這個(gè)時(shí)間決定了多久會(huì)把readWriteCacheMap的緩存更新到readCacheMap上
    response-cache-update-interval-ms: 3000
    # 默認(rèn)60s. 啟用主動(dòng)失效,并且每次主動(dòng)失效檢測(cè)間隔為5s.
    eviction-interval-timer-in-ms: 5000
  instance:
    # 默認(rèn)90s. 服務(wù)過(guò)期時(shí)間配置,超過(guò)這個(gè)時(shí)間沒(méi)有接收到心跳EurekaServer就會(huì)將這個(gè)實(shí)例剔除.
    # 注意,EurekaServer一定要設(shè)置eureka.server.eviction-interval-timer-in-ms否則這個(gè)配置無(wú)效,這個(gè)配置一般為服務(wù)刷新時(shí)間配置的三倍
    lease-expiration-duration-in-seconds: 15
    # 默認(rèn)30s. 服務(wù)刷新時(shí)間配置,每隔這個(gè)時(shí)間會(huì)主動(dòng)心跳一次
    lease-renewal-interval-in-seconds: 5

Eureka Client

eureka:
  client:
    # eureka client刷新本地緩存時(shí)間
    registryFetchIntervalSeconds: 5
ribbon:
  # eureka客戶(hù)端ribbon刷新時(shí)間
  ServerListRefreshInterval: 5000

友情提醒

這套配置,比較適合在開(kāi)發(fā)階段使用,因?yàn)槲覀兿M貑⒌姆?wù)能盡快可用。但是線(xiàn)上環(huán)境就需要根據(jù)具體情況更改配置,當(dāng)然如果線(xiàn)上環(huán)境的服務(wù)實(shí)例數(shù)比較少,也是可以考慮使用上述配置。

推薦閱讀

Spring Cloud 進(jìn)階玩法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容