本文介紹MSE微服務治理無損上下線的常見問題。
原先操作面板上的進階功能去哪了?對已經接入的應用有什麼影響?我還想開啟或關閉應該怎麼操作?
應用新接入服務治理的情況下,無需關注本問題內容。
在舊版的無損上下線控制台互動中,提供了進階功能選項。而進階功能涉及比較多的微服務概念,所以新版互動從簡化使用的角度考慮,在將其進行了隱藏。舊版的進階功能包含兩個子功能:
通過就緒檢查前完成服務註冊。
新版中仍然提供並預設開啟,如果您的應用原先未開啟,當您在控制台無損上下線介面重新開啟無損上線後會自動開啟。如果您的應用原先已經開啟了該功能,我們不推薦您關閉。該功能在預設開啟的情況下,不會對應用帶來負面影響。預設開啟的情況下,可以規避發版時特定情境下流量跌零的風險,具體可以參考為什麼配置55199/readiness。
通過就緒檢查前完成服務預熱。
新版不再提供,該功能最初的設計目的是用來保證預熱效果達到預期狀態,避免出現開啟預熱的服務QPS曲線出現陡升的情況。本質上是通過延遲K8s就緒檢測通過的時間,來延長整體的發版時間,保障新節點可以有足夠的時間進行預熱,並且讓老節點在這個過程中繼續承擔一部分流量,不會被快速下掉。這樣就可以保證預熱的QPS曲線呈現出是一個緩慢升高的狀態。如果在發版過程中,新節點在預熱時,老節點已經全部下線,那麼新節點就需要承受所有的線上流量,從而無法實現“小流量”的預熱。原先已經開啟該功能的應用不會受到影響,但是新應用設定規則時無法再對該功能進行開啟,如果您之前開啟了該功能,我們也不推薦您關閉。該功能在開啟的情況下,不會對應用帶來負面影響。在新版互動中,想要服務小流量預熱達到預期效果,可參見小流量預熱的最佳實務。
小流量預熱的原理是什嗎?為什麼小流量預熱需要提供者、消費者都接入服務治理?
當消費者對某個服務進行調用時,會對該服務的提供者進行選擇。在提供者應用開啟小流量預熱的情況下,服務治理對這裡“選擇提供者”的過程進行了增強。在消費者選擇提供者時,會計算每個提供者的權重大小(0%~100%),權重越大的提供者節點,被選擇和調用的機率就會越高。開啟小流量預熱的提供者在剛啟動時,消費者對其計算的權重很低,因此預熱的節點被調用的機率也會變低,隨著時間增加,這個權重計算結果會不斷增大,最終達到100%,達到100%時,預熱流程就結束了,開始和正常節點一樣接收流量。提供者會在服務註冊的中繼資料中,帶上自身啟動的時間,以供消費者進行權重計算。這個過程需要提供者、消費者雙方都開啟服務治理才能實現。
小流量預熱的“開始”會在應用收到第一筆請求後觸發,當預熱過程已經達到配置的預熱時間長度後(預設120秒),小流量預熱結束。如果應用一直沒有收到外部流量,則不會觸發預熱的開始。
小流量預熱觸發的前提是有外部流量進來,這就要求服務已經完成了註冊。如果您發現應用還未進行服務註冊,卻已經開始了小流量預熱(即您在控制台觀察到預熱開始事件出現在服務註冊事件之前),您可以參考為什麼應用先出現預熱事件後出現服務註冊事件?來解決。
為什麼我的預熱曲線不符合預期?該如何解決?
閱讀該問題之前,建議您先瞭解一下服務小流量預熱的原理。
正常情況下小流量預熱時,應用的QPS曲線圖如下:

但是有些時候由於不合理或不支援的使用情境,進行小流量預熱的應用,其QPS曲線圖形狀會不太符合預期(緩慢上升),下面是兩種常見的不符合預期的情況:
QPS 曲線中途出現陡升現象

這種現象一般發生在服務發布的情境,如果在服務發布時,新節點的預熱還沒有達到指定時間長度,老節點就被下線了,那麼消費者端在選擇提供者時,就無法實現控制新節點被“低機率”調用到了。所以會在 QPS 曲線圖中看到,某個新節點的 QPS 曲線在前半段時緩慢上線的態勢,達到某個時間節點後,老節點被全部下線,QPS 曲線就出現陡升現象了。您可以參考小流量預熱的最佳實務,來解決QPS曲線陡升的問題。
QPS 曲線未呈現緩升趨勢

出現這種現象,建議檢查對該應用發起請求的消費者應用已經接入服務治理,如果消費者端沒接入,則考慮將消費者應用都接入服務治理,就可以解決該問題。如果您需要預熱的應用,其流量來自外部(比如Java網關),這種情境下消費者是沒有接入服務治理的,小流量預熱也無法支援這種情境。
小流量預熱的最佳實務是什嗎?
在滾動發布的情況下,經常會出現預熱不充分的問題。您可以參考以下實踐,來保證服務預熱達到預期效果:
配置最小準備時間(推薦):您可以為工作負載配置
.spec.minReadySeconds來控制pod就緒後達到可用狀態時的時間間隔,並且設定該參數的值大於pod的小流量預熱時間長度,以使得K8s等待 pod 預熱完畢後再繼續滾動發布。 如果您使用的是ACK,您可以直接在容器平台上找到您的應用,在 更多 > 升級策略 > 滾動升級 > 最小準備時間(minReadySeconds) 中直接設定。(設定 minReadySeconds可以在發布時,讓新啟動的pod狀態達到ready並維持固定時間長度之後,才會繼續發布)使用分批發布(推薦):您可以考慮使用OpenKruise等方式,實現工作負載的分批發布,並且控制每個批次發布時的時間間隔大於小流量預熱時間長度,保證批次內的新節點預熱充分後,再繼續發布一下次批次的節點。
此外,延長Readiness就緒檢測的初始探測時間(不推薦),也是一種方式,您可以增加工作負載Readiness 的首次探測延遲時間長度(initialDelaySeconds),並且大於小流量預熱時間長度、延遲註冊時間長度、應用啟動時間三者之和。注意,應用啟動時間一般需要觀測實際日誌輸出來得出,並且隨著業務發展,應用的啟動時間也會隨之變化;此外,延遲 Readiness 通過的時間,也會導致新啟動的節點遲遲無法被加入到 K8s Service的Endpoint中,因此我們不推薦您使用這種方式來保證預熱效果達到最佳。
如果您按照最佳實務進行操作後,發現預熱QPS曲線仍然不符合預期,可以考慮應用接收的流量,是否都來自於已經接入服務治理的消費者應用,如果有消費者沒有接入服務治理,或者存在來自於外部負載平衡的調用流量,那麼應用預熱時的QPS曲線圖也會不符合預期。
55199/readiness是做什麼的?為什麼不配置55199/readiness會有流量跌0的風險?
55199/readiness是MSE微服務治理提供的一套內建的、HTTP類型的就緒檢查連接埠,當應用的K8s就緒檢查配置成55199/readiness時,在新節點上線階段,如果該節點尚未完成服務註冊,則就緒檢查返回500;如果該節點已經完成服務註冊,則就緒檢查返回 200。
按照 K8s 預設的發布策略,新節點沒有就緒,老節點就不會下線。當就緒檢查配置了55199/readiness之後,新節點完成服務註冊之後,才會進入就緒狀態,即只有在新節點完成服務註冊的情況下,老節點才會下線。這樣就會保證註冊中心上該服務一直會有可用的節點。如果您不配置55199/readiness,可能會在服務發布時,新節點尚未註冊,老節點就被下線,進而導致註冊中心上該服務沒有可用節點,進而導致該服務的所有消費者在調用時因為沒有提供者而發生報錯,從而產生該服務的流量跌0。因此我們強烈建議您開啟無損上線,並為應用配置55199/readiness就緒檢測。
如果您的應用所使用的探針版本低於4.1.10,就緒檢測的路徑需要配置成/health,而非 /readiness。查看探針版本方式:MSE 控制台 > 治理中心 > 應用治理 > 單擊對應的應用 > 節點詳情,右側可以看到探針版本。
為什麼應用先出現預熱事件後出現服務註冊事件?如何解決?
在目前的版本下,服務收到了第一筆外部請求時,就會開始預熱流程,並且上報預熱開始事件。而有些時候,應用收到的第一筆請求,未必是微服務調用請求,因此這種請求也不會觸發商務邏輯的預熱。比如應用的工作負載配置了K8s的Liveness探針,在新節點上線時,即便還沒有進行服務註冊操作,只要K8s對Liveness進行了探測,就會判定預熱已經開始。
為了避免這種情況, 您可以在提供者應用工作負載的環境變數中,配置如下參數,來忽略這些請求對預熱邏輯的觸發:
# 忽略路徑為 /xxx、/yyy/zz 的請求對預熱流程的觸發
profile_micro_service_record_warmup_ignored_path="/xxx,/yyy/zz"該參數也支援 Jvm 啟動參數的方式進行配置。
該參數的值不支援正則匹配。
主動通知是做什麼的?什麼時候需要開啟主動通知?
主動通知是無損下線功能模組提供的一種進階能力,該功能可以在SpringCloud提供者下線時,讓提供者主動發起一次網路請求到服務消費者,告知其自身已經下線。消費者收到通知後,不會再對該節點進行調用。一般情況下,當提供者消費者都使用SpringCloud架構時,消費者本地會緩衝提供者節點列表。在某些情境下,即便消費者收到註冊中心的通知,也可能沒有及時重新整理本機快取,進而導致消費者對下線的節點仍然發起調用。主動通知則很好地解決了這個問題。
主動通知功能預設關閉,因為開啟服務治理之後,預設的無損下線方案中,下線階段的提供者收到請求時,會在響應中加入一個特殊的header,消費者收到響應時會識別該header,並且不再調用該提供者節點。因此,只要在提供者下線時,消費者有流量到達下線的提供者,就會感知到該提供者已經下線,並且會自動將其“拉黑”。而如果在提供者下線的這段時間內(一般30秒左右),消費者沒有請求到達正在下線的提供者,消費者就有可能未感知到該提供者節點已經下線,有可能會在提供者剛好走完下線流程、即將停機時,消費者請求正好過來,此時就會出現請求報錯的問題。這個時候,就需要開啟主動通知。換句話說,如果消費者的流量非常“稀疏”,就建議您為提供者開啟主動通知的功能。
為什麼已經看到無損下線事件後,流量還是沒有快速降為0?
一般情況下,看到無損下線事件後,流量會在短時間內快速降為0。如果沒有降為0,可能的原因和解決方案如下:
該應用收到了非微服務方式的調用,比如收到來自外部負載平衡器的流量,或者存在本地指令碼、定時任務等調用方式產生了流量。
目前無損上下線只支援治理內部微服務調用的流量,上述情境並不在無損上下線功能支援的範圍之內。建議您根據這些基礎設施、架構提供的優雅下線特性來定製相應的解決方案。
該應用需要開啟主動通知,但是沒有開啟。(您可以參考本文瞭解主動通知)
建議您開啟主動通知後再次觀測下線曲線是否符合預期。
該應用使用的架構版本不在支援的範圍之內,服務治理無損上下線支援的架構可以參考:微服務治理支援的Java架構。
如果您發現應用使用的架構版本不再支援版本之中,可以考慮對應用的架構版本進行升級。
應用接入無損上下線後,現在發版時間非常長,怎麼辦?
您可以通過如下步驟檢查應用是否開啟過【通過就緒檢查前完成服務預熱】。
登入MSE治理中心控制台,並在頂部功能表列選擇地區。
在左側導覽列,選擇治理中心 > 應用治理。
在應用列表頁面,單擊目標應用,選擇流量治理 > 無損上下線頁簽。
在無損上下線頁簽中,使用 F12 按鍵開啟網頁調試面板。在Network一欄中,搜尋請求
GetLosslessRuleByApp(如果沒看到可以重新整理一下頁面),在 Response 中,可以看到 Data 中 Related 欄位值是否為 true。如果為 true 的話說明應用很久之前開啟過【通過就緒檢查前完成服務預熱】這一功能(該功能目前已經不再提供),這個功能在開啟的情況下可能會導致發版時間變長,建議您提交工單來關閉該功能。
MSE 服務治理提供的 55199/readiness 是做什麼的?為什麼有時候 mse readiness 一直不通過?
K8s 提供了三種可選的探針檢查,分別是啟動探針,存活探針,就緒探針:
啟動探針:用於檢測應用是否啟動成功。僅在 Pod 啟動階段進行探測,如果在 Pod 啟動階段,多次探測失敗並達到配置的失敗閾值時,會觸發 Pod 重啟。
存活探針:用於檢測應用當前是否存活。會在啟動探測成功後開始探測,探測會伴隨 Pod 整個生命週期。多次探測失敗並達到配置的失敗閾值時,會觸發 Pod 重啟。
就緒探針:用於檢測應用目前狀態是否就緒。會在啟動探測成功後開始探測,探測會伴隨 Pod 整個生命週期。多次探測失敗並達到配置的失敗閾值時,K8s 會將 Pod 的狀態置為 not ready,但不會觸發 Pod 的重啟。在應用發布時,就緒探針也可以用來控制發布的節奏,按照預設的發布策略,如果新啟動的 Pod 一直沒有達到 ready 狀態,K8s 會暫停發布流程,等待新 Pod 狀態變為 ready。
在您的服務接入 MSE 服務治理後,您可以使用 MSE 服務治理內建的 55199/readiness 來提供服務就緒檢測配置。 配置後K8s 的就緒探測會在應用完成服務註冊後才會通過,這樣可以保證發布過程中,新拉起的 Pod 都已經完成了微服務註冊中心的註冊,老的 Pod 才會被 K8s 下線並且進行註冊中心登出,讓服務的調用方一直有可用的節點去發起調用,避免出現無可用服務的異常。關於為什麼需要配置 mse readiness,可參見服務註冊狀態檢查。
如果您 mse readiness 一直沒有通過,一般有三種可能的原因:
當前服務是否未開啟無損上線。未開啟無損上線的情況下,mse 55199/readiness 介面不會開放,所以 readiness 檢查不會通過。
當前應用沒有接入服務治理。可以檢查服務治理探針目錄下是否存在探針日誌。K8s 環境下探針目錄預設為
/home/admin/.opt/AliyunJavaAgent或/home/admin/.opt/ArmsAgent目錄。如果目錄下沒有 logs 目錄,說明應用服務治理接入失敗,請提交工單聯絡我們。當前應用因為啟動探針或存活探針失敗達到閾值,一直在重啟應用。因為應用沒有啟動完畢,所以 mse readiness 也不會通過。可以後台檢查一下 Pod 的 K8s 事件,是否存在啟動探針或存活探針失敗相關的事件。