🔥Serverless 微服務優雅關機實踐| 🏆 技術專題第七期徵文

應對業務服務的發佈和服務升級時,線上出現問題的可能性很高,就 Serverless 架構下討論如何保障上線過程當中服務的優雅下線java

Solomon_肖哥彈架構 跟你們「彈彈」 如何更加優雅的進行服務下線,貫穿南北與東西流量的調度方案。後端

平時發佈過程否遇到如下問題:服務器

  • 發佈過程當中,出現正在執行的請求被中斷
  • 下游服務節點已經下線,上游依然繼續調用已經下線的節點致使請求報錯,進而致使業務異常
  • 發佈過程形成數據不一致,須要對髒數據進行修復。

一般發版安排在凌晨兩三點,在業務流量比較小的時候。那如何解決上面的問題,如何保證應用發佈過程穩定、高效,保證業務無損。markdown

場景分析

上圖描述了咱們使用微服務架構開發應用的一個常見場景,咱們先看下這個場景的服務調用關係:架構

  • 服務 B、C 把服務註冊到註冊中心,服務 A、B 從註冊中心發現須要調用的服務;
  • 業務流量從負載均衡打到服務 A,在 SLB 上配置服務 A 實例的健康檢查,當服務 A 有實例停機的時候,相應的實例從 SLB 摘掉;服務 A 調用服務 B,服務 B 再調用服務 C;

上圖有兩類流量app

  • 南北向流量:
    • 即經過 SLB 轉發到後端服務器的業務流量,如業務流量 -> SLB -> A 的調用路徑
  • 東西向流量:
    • 經過註冊中心服務中心服務發現來調用的流量,如 A -> B 的調用路徑

南北向流量

南北向流量問題

當服務 A 發佈的時候,服務 A1 實例停機後,SLB 根據健康檢查探測到服務 A1 下線,而後把實例從 SLB 摘掉。實例 A1 依賴 SLB 的健康檢查從 SLB 上摘掉,通常須要幾秒到十幾秒的時間,在這個過程當中,若是 SLB 有持續的流量打入,就會形成一些請求繼續路由到實例 A1,致使請求失敗;負載均衡

服務 A 在發佈的過程當中,如何保證通過 SLB 的流量不報錯?咱們接着看下 SAE 是如何作的。框架

南北向流量優雅升級方案

請求失敗的緣由在於後端服務實例先中止掉,而後才從 SLB 摘掉,那咱們是否是能夠先從 SLB 摘掉服務實例,而後再對實例進行升級呢?less

按照這個思路,SAE 基於 K8S service 的能力給出了一種方案微服務

  • 當用戶在經過 SAE 爲應用綁定 SLB 時,SAE 會在集羣中建立一個 service 資源,並把應用的實例和 service 關聯,CCM 組件會負責 SLB 的購買、SLB 虛擬服務器組的建立,而且把應用實例關聯的 ENI 網卡添加到虛擬服務器組中,用戶能夠經過 SLB 來訪問應用實例;
  • 當應用發佈時,CCM 會先把實例對應的 ENI 從虛擬服務器組中摘除,而後再對實例進行升級,從而保證流量不丟失。

這就是 SAE 對於應用升級過程當中關於南北向流量的保障方案。

東西向流量

東西向流量問題

在傳統的發佈流程中,服務提供者中止再啓動,服務消費者感知到服務提供者節點中止的流程以下:

  1. 服務發佈前,消費者根據負載均衡規則調用服務提供者,業務正常。
  2. 服務提供者 B 須要發佈新版本,先對其中的一個節點進行操做,首先是中止 java 進程。
  3. 服務中止過程,又分爲主動註銷和被動註銷,主動註銷是準實時的,被動註銷的時間由不一樣的註冊中心決定,最差的狀況會須要 1 分鐘。
    • 若是應用是正常中止,Spring Cloud 和 Dubbo 框架的 Shutdown Hook 能正常被執行,這一步的耗時能夠忽略不計。
    • 若是應用是非正常中止,好比直接使用 kill -9 中止,或者 Docker 鏡像構建的時候 java 應用不是 1 號進程且沒有把 kill 信號傳遞給應用。那麼服務提供者不會主動去註銷服務節點,而是在超過一段時間後因爲心跳超時而被動地被註冊中心摘除。
  4. 服務註冊中心通知消費者,其中的一個服務提供者節點已下線。包含推送和輪詢兩種方式,推送能夠認爲是準實時的,輪詢的耗時由服務消費者輪詢間隔決定,最差的狀況下須要 1 分鐘。
  5. 服務消費者刷新服務列表,感知到服務提供者已經下線了一個節點,這一步對於 Dubbo 框架來講不存在,可是 Spring Cloud 的負載均衡組件 Ribbon 默認的刷新時間是 30 秒 ,最差狀況下須要耗時 30 秒。
  6. 服務消費者再也不調用已經下線的節點。

從第 2 步到第 6 步的過程當中,Eureka 在最差的狀況下須要耗時 2 分鐘,Nacos 在最差的狀況下須要耗時 50 秒。在這段時間內,請求都有可能出現問題,因此發佈時會出現各類報錯,同時還影響用戶的體驗,發佈後又須要修復執行到一半的髒數據。最後不得不每次發版都安排在凌晨兩三點發布,心驚膽顫,睡眠不足,苦不堪言。

東西向流量優雅升級方案

在傳統發佈流程中,客戶端有一個服務調用報錯期,緣由就是客戶端沒有及時感知到服務端下線的實例。在傳統發佈流程中,主要是藉助註冊中心通知消費者來更新服務提供者列表,那能不能繞過註冊中心,服務提供者直接通知服務消費者呢?答案是確定的,咱們主要作了兩件事情:

  • 服務提供者應用在發佈先後主動向註冊中心註銷應用,並將應用標記爲已下線的狀態;將原來的中止進程階段註銷服務變成了 prestop 階段註銷服務。
  • 在接收到服務消費者請求時,首先會正常處理本次調用,並通知服務消費者此節點已下線,服務消費者會當即從調用列表刪除此節點;在這以後,服務消費者再也不調用已經下線的節點。這是將原來的依賴於 註冊中心推送,作到了服務提供者直接通知消費者從調用列表中摘除本身。

經過上面這個方案,就使得下線感知的時間大大減短,從原來的分鐘級別作到準實時,確保應用在下線時能作到業務無損。

分批發布和灰度發佈

上文介紹的是 SAE 在處理優雅下線方面的一些能力,在應用升級的過程當中,只有實例的優雅下線是不夠的,還須要有一套配套的發佈策略,保證咱們新業務是可用的,SAE 提供分批發布和灰度發佈的能力,可使得應用的發佈過程更加省心省力;

咱們先介紹下灰度發佈,某應用包含 10 個應用實例,每一個應用實例的部署版本爲 Ver.1 版本,現需將每一個應用實例升級爲 Ver.2 版本。

從圖中能夠看出,在發佈的過程當中先灰度 2 臺實例,在確認業務正常後,再分批發布剩餘的實例,發佈的過程當中始終有實例處於運行狀態,實例升級過程當中依照上面的方案,每一個實例都有優雅下線的過程,這就保證了業務無損。

再來看下分批發布,分批發布支持手動、自動分批;仍是上面的 10 個應用實例,假設將全部應用實例分 3 批進行部署,根據分批發布策略,該發佈流程如圖所示,就再也不具體介紹了。

你的點贊關注Solomon_肖哥彈架構持續的動力。

🏆 技術專題第七期 |萬物皆可 Serverless

相關文章
相關標籤/搜索