業務繁忙的系統,原則上是不允許停機的,那么問題來了,如果真有嚴重的bug要修復,不得不發布,怎么做到不停機發布,對業務無感知呢?
eureka 提供了一系列rest url,可以對注冊實例進行操作,比如:將服務離線/上線,注冊/注銷,動態修改meta元數據等,詳情見本文最后的參考wiki。
不停機發布的思路:
通常spring-cloud微服務是以集群方式部署的,而且內網微服務,通過zuul網關來進行訪問,再次搬出上一篇中的示意架構圖:
zuul網關層一般只是用於路由轉發等輕量級的處理,不會涉及太多復雜的業務邏輯,發布相對較少,經常修改的多半是背后的微服務,對於微服務的不停機發布,思路如下:
1、先將目標機的服務狀態調整成“下線”
即:利用 PUT /eureka/apps/appID/instanceID/status?value=OUT_OF_SERVICE 這個rest接口
shell終端下,可以類似下面這樣直接輸入:
curl -X PUT -i -H "Authorization:Basic d2**G9zOndSVEwxaUpaRVp3MFBU****" http://10.1.2.3:7001/eureka/apps/DEMO-SERVICE/10.0.2.*:7031/status?value=OUT_OF_SERVICE
注:
-X PUT 表示這是PUT請求
-H 表示設置http頭,如果背后的微服務,啟用了basic auth安全認證,不加頭的話,會提示沒有權限,至於Authorization:Basic 后面的這一串密文是怎么來的,后面會講到
http://10.1.2.3:7001/ 這是eureka-server所在的ip或域名
DEMO-SERVICE 是要下線的服務名稱
10.0.2.*:7031 是服務實例的instanceId
參數下圖:
當然,上面這個請求,也可以用postman之類的圖形化工具來進行:
對於設置了Basic Auth的微服務,可參考上圖,設置用戶名、密碼,然后點擊Update Request,就得到了Header中的值(如下圖)
調用成功后,再回到eureka server中觀察,可以發現該服務已經下線:
注:下線后,還要經過幾次心跳,zuul才會感知到這台節點的變化,建議下線后,先等待1-2分鍾,這樣新的請求,就不會通過zuul轉發到這台目標機器。
2、對目標機進行常規發布
經常剛才的步驟,目標機上已經沒有新請求進來,可以相對安全的進行程序更新發布
注:如果發布過程中,一般要先停止應用,建議用kill pid,不要帶-9強殺,以防萬一還有未執行完成的請求。另外,發布重啟后,也建議等待1-2分鍾,等應用徹底啟動好,並注冊到eureka server上,讓zuul感知該節點已重新上線。
3、對其它節點重復1,2的操作。
其它技巧:
上一篇還提到了如何做灰度發布,其原理是通過meta-map元數據來實現,發布完成后,也可以通過eureka的rest url來動態修改元數據,讓指定節點變成灰度機器,類似:
curl -X PUT -i -H "Authorization:Basic d2lucG9zOndSVEwxaUpaRVp1MFBUMm9=" http://10.0.19.71:7001/eureka/apps/DEMO-SERVICE/10.0.19.73:7031/metadata?gated-launch=true
參考文章:
https://github.com/Netflix/eureka/wiki/Eureka-REST-operations