Spring Cloud優(yōu)雅下線+灰度發(fā)布
前言
kill PID和kill -9 PID都是暴力殺死服務(wù),相對于kill -9 PID來說,kill PID就是優(yōu)雅的。但如果單獨(dú)拿kill PID出來說,我們能說它是優(yōu)雅的下線策略嗎?肯定不是啊,就是這個(gè)道理。優(yōu)雅下線
常見的下線方式
方式一:kill PID
Shutdown hook,應(yīng)用本身的下線也是優(yōu)雅的,但如果你的服務(wù)發(fā)現(xiàn)組件使用的是 Eureka,那么默認(rèn)最長會有 90 秒的延遲,其他應(yīng)用才會感知到該服務(wù)下線,這意味著:該實(shí)例下線后的 90 秒內(nèi),其他服務(wù)仍然可能調(diào)用到這個(gè)已下線的實(shí)例。因此,該方式是不夠優(yōu)雅的 。方式二:/shutdown端點(diǎn)
/shutdown端點(diǎn),可以借助它實(shí)現(xiàn)優(yōu)雅停機(jī)。/shutdown端點(diǎn):management:
endpoint:
shutdown:
enabled: true
endpoints:
web:
exposure:
include: shutdown
curl -X http://你想停止的服務(wù)地址/actuator/shutdown方式三:/pause端點(diǎn)
/pause端點(diǎn),利用該端點(diǎn)可實(shí)現(xiàn)優(yōu)雅下線。/pause端點(diǎn):management:
endpoint:
# 啟用pause端點(diǎn)
pause:
enabled: true
# 啟用restart端點(diǎn),之所以要啟用restart端點(diǎn),是因?yàn)閜ause端點(diǎn)的啟用依賴restart端點(diǎn)的啟用
restart:
enabled: true
endpoints:
web:
exposure:
include: pause,restart
/actuator/pause端點(diǎn):curl -X POST http://你想停止的服務(wù)實(shí)例地址/actuator/pause
/pause端點(diǎn),將要下線的應(yīng)用標(biāo)記為DOWN,但不去真正停止應(yīng)用;然后過一定的時(shí)間(例如 90 秒,或者自己做個(gè)監(jiān)控,看當(dāng)前實(shí)例的流量變成 0 后)再去停止應(yīng)用,例如kill應(yīng)用。
方式四:/service-registry端點(diǎn)
/service-registry端點(diǎn):management:
endpoints:
web:
exposure:
include: service-registry
/actuator/service-registry端點(diǎn):curl -X "POST" "http://localhost:8000/actuator/service-registry?status=DOWN" \
-H "Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8"

優(yōu)雅的下線方式
/service-registry端點(diǎn),將服務(wù)標(biāo)記為DOWN,然后監(jiān)控服務(wù)的流量,當(dāng)流量為 0 時(shí),即可升級該服務(wù)。當(dāng)然,這里假設(shè)我們部署了多個(gè)服務(wù)實(shí)例,當(dāng)一個(gè)服務(wù)實(shí)例DOWN掉之后,其他服務(wù)實(shí)例仍然是可以提供服務(wù)的,如果就部署一臺服務(wù)的話,那么討論優(yōu)不優(yōu)雅就沒那么重要了。EurekaAutoServiceRegistration對象達(dá)到優(yōu)雅下線的目標(biāo)。執(zhí)行 eurekaAutoServiceRegistration.start()方法時(shí),當(dāng)前服務(wù)向 Eureka 注冊中心注冊服務(wù);執(zhí)行 eurekaAutoServiceRegistration.stop()方法時(shí),當(dāng)前服務(wù)會向 Eureka 注冊中心進(jìn)行反注冊,注冊中心收到請求后,會將此服務(wù)從注冊列表中刪除。
@RestController
@RequestMapping(value = "/graceful/registry-service")
public class GracefulOffline {
@Autowired
private EurekaAutoServiceRegistration eurekaAutoServiceRegistration;
@RequestMapping("/online")
public String online() {
this.eurekaAutoServiceRegistration.start();
return "execute online method, online success.";
}
@RequestMapping("/offline")
public String offline() {
this.eurekaAutoServiceRegistration.stop();
return "execute offline method, offline success.";
}
}
灰度發(fā)布
藍(lán)綠部署
部署集群 1 的應(yīng)用(初始狀態(tài)),將所有外部請求的流量都打到這個(gè)集群上 部署集群 2 的應(yīng)用,集群 2 的代碼與集群 1 不同,如新功能或者 Bug 修復(fù)等 將流量從集群 1 切換到集群 2 如集群 2 測試正常,就刪除集群 1 正在使用的資源(例如實(shí)例),使用集群 2 對外提供服務(wù)
滾動部署
沒有一個(gè)確定 OK 的環(huán)境。使用藍(lán)綠部署,我們能夠清晰地知道老版本是 OK 的,而使用滾動發(fā)布,我們無法確定。 修改了現(xiàn)有的環(huán)境。 如果需要回滾,很困難。舉個(gè)例子,在某一次發(fā)布中,我們需要更新 100 個(gè)實(shí)例,每次更新 10 個(gè)實(shí)例,每次部署需要 5 分鐘。當(dāng)滾動發(fā)布到第 80 個(gè)實(shí)例時(shí),發(fā)現(xiàn)了問題,需要回滾。這時(shí),我們估計(jì)就要瘋了。 有的時(shí)候,我們還可能對系統(tǒng)進(jìn)行動態(tài)伸縮,如果部署期間,系統(tǒng)自動擴(kuò)容/縮容了,我們還需判斷到底哪個(gè)節(jié)點(diǎn)使用的是哪個(gè)代碼。盡管有一些自動化的運(yùn)維工具,但是依然令人心驚膽戰(zhàn)。
金絲雀部署
準(zhǔn)備好部署各個(gè)階段的工件,包括:構(gòu)建工件,測試腳本,配置文件和部署清單文件 從負(fù)載均衡列表中移除掉“金絲雀”服務(wù)器 升級“金絲雀”應(yīng)用(切斷原有流量并進(jìn)行部署) 對應(yīng)用進(jìn)行自動化測試 將“金絲雀”服務(wù)器重新添加到負(fù)載均衡列表中(連通性和健康檢查) 如果“金絲雀”在線使用測試成功,升級剩余的其他服務(wù)器(否則就回滾)
轉(zhuǎn)自:CG國斌
鏈接:https://blog.csdn.net/qq_35246620/article/details/109166722
評論
圖片
表情
