1. 程式人生 > 其它 >關於Servlet中頁面的跳轉實現

關於Servlet中頁面的跳轉實現

作者 | 行鬆 阿里巴巴雲原生團隊

應用釋出、服務升級一直是一個讓開發和運維同學既興奮又擔心的事情。

興奮的是有新功能上線,自己的產品可以對使用者提供更多的能力和價值;擔心的是上線的過程會不會出現意外情況影響業務的穩定性。確實,在應用釋出和服務升級時,線上問題出現的可能性更高,本文我們將結合 Serverless 應用引擎(以下簡稱 SAE)就 Serverless 架構下,討論如何保障上線過程中服務的優雅下線。

在平時的釋出過程中,我們是否遇到過以下問題:

  • 釋出過程中,出現正在執行的請求被中斷?

  • 下游服務節點已經下線,上游依然繼續呼叫已經下線的節點導致請求報錯,進而導致業務異常?

  • 釋出過程造成資料不一致,需要對髒資料進行修復。

有時候,我們把發版安排在凌晨兩三點,趕在業務流量比較小的時候,心驚膽顫、睡眠不足、苦不堪言。那如何解決上面的問題,如何保證應用釋出過程穩定、高效,保證業務無損呢?首先,我們來梳理下造成這些問題的原因。

場景分析

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

  • 服務 B、C 把服務註冊到註冊中心,服務 A、B 從註冊中心發現需要呼叫的服務;

  • 業務流量從負載均衡打到服務 A,在 SLB 上配置服務 A 例項的健康檢查,當服務 A 有例項停機的時候,相應的例項從 SLB 摘掉;服務 A 呼叫服務 B,服務 B 再呼叫服務 C;

圖中有兩類流量,南北向流量(即通過 SLB 轉發到後端伺服器的業務流量,如業務流量 -> SLB -> A 的呼叫路徑)和東西向流量(通過註冊中心服務中心服務發現來呼叫的流量,如 A -> B 的呼叫路徑),下面針對這兩類流量分別進行分析。

南北向流量

南北向流量存在問題

當服務 A 釋出的時候,服務 A1 例項停機後,SLB 根據健康檢查探測到服務 A1 下線,然後把例項從 SLB 摘掉。例項 A1 依賴 SLB 的健康檢查從 SLB 上摘掉,一般需要幾秒到十幾秒的時間,在這個過程中,如果 SLB 有持續的流量打入,就會造成一些請求繼續路由到例項 A1,導致請求失敗;

服務 A 在釋出的過程中,如何保證經過 SLB 的流量不報錯?我們接著看下 SAE 是如何做的。

南北向流量優雅升級方案

如上文所提,請求失敗的原因在於後端服務例項先停止掉,然後才從 SLB 摘掉,那我們是不是可以先從 SLB 摘掉服務例項,然後再對例項進行升級呢?

按照這個思路,SAE 基於 K8S service 的能力給出了一種方案,當用戶在通過 SAE 為應用繫結 SLB 時,SAE 會在叢集中建立一個 service 資源,並把應用的例項和 service 關聯,CCM 元件會負責 SLB 的購買、SLB 虛擬伺服器組的建立,並且把應用例項關聯的 ENI 網絡卡新增到虛擬伺服器組中,使用者可以通過 SLB 來訪問應用例項;當應用釋出時,CCM 會先把例項對應的 ENI 從虛擬伺服器組中摘除,然後再對例項進行升級,從而保證流量不丟失。

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

東西向流量

東西向流量存在問題

在討論完南北向流量的解決方案後,我們再看下東西向流量,傳統的釋出流程中,服務提供者停止再啟動,服務消費者感知到服務提供者節點停止的流程如下:

  1. 服務釋出前,消費者根據負載均衡規則呼叫服務提供者,業務正常。

  2. 服務提供者 B 需要釋出新版本,先對其中的一個節點進行操作,首先是停止 java 程序。

  3. 服務停止過程,又分為主動登出和被動登出,主動登出是準實時的,被動登出的時間由不同的註冊中心決定,最差的情況會需要 1 分鐘。

    1. 如果應用是正常停止,Spring Cloud 和 Dubbo 框架的 Shutdown Hook 能正常被執行,這一步的耗時可以忽略不計。

    2. 如果應用是非正常停止,比如直接使用 kill -9 停止,或者 Docker 映象構建的時候 java 應用不是 1 號程序且沒有把 kill 訊號傳遞給應用。那麼服務提供者不會主動去登出服務節點,而是在超過一段時間後由於心跳超時而被動地被註冊中心摘除。

  4. 服務註冊中心通知消費者,其中的一個服務提供者節點已下線。包含推送和輪詢兩種方式,推送可以認為是準實時的,輪詢的耗時由服務消費者輪詢間隔決定,最差的情況下需要 1 分鐘。

  5. 服務消費者重新整理服務列表,感知到服務提供者已經下線了一個節點,這一步對於 Dubbo 框架來說不存在,但是 Spring Cloud 的負載均衡元件 Ribbon 預設的重新整理時間是 30 秒 ,最差情況下需要耗時 30 秒。

  6. 服務消費者不再呼叫已經下線的節點。

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

東西向流量優雅升級方案

經過上文的分析,我們看,在傳統釋出流程中,客戶端有一個服務呼叫報錯期,原因就是客戶端沒有及時感知到服務端下線的例項。在傳統釋出流程中,主要是藉助註冊中心通知消費者來更新服務提供者列表,那能不能繞過註冊中心,服務提供者直接通知服務消費者呢?答案是肯定的,我們主要做了兩件事情:

  1. 服務提供者應用在釋出前後主動向註冊中心登出應用,並將應用標記為已下線的狀態;將原來的停止程序階段登出服務變成了 prestop 階段登出服務。

  2. 在接收到服務消費者請求時,首先會正常處理本次呼叫,並通知服務消費者此節點已下線,服務消費者會立即從呼叫列表刪除此節點;在這之後,服務消費者不再呼叫已經下線的節點。這是將原來的依賴於 註冊中心推送,做到了服務提供者直接通知消費者從呼叫列表中摘除自己。

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

分批發布和灰度釋出

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

我們先介紹下灰度釋出,某應用包含 10 個應用例項,每個應用例項的部署版本為 Ver.1 版本,現需將每個應用例項升級為 Ver.2 版本。

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

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

最後針對在 SAE 上應用灰度釋出的過程進行演示,點選即可觀看演示過程:https://developer.aliyun.com/lesson_2026_19009

課程推薦

為了更多開發者能夠享受到 Serverless 帶來的紅利,這一次,我們集結了 10+ 位阿里巴巴 Serverless 領域技術專家,打造出最適合開發者入門的 Serverless 公開課,讓你即學即用,輕鬆擁抱雲端計算的新正規化——Serverless。點選即可免費觀看課程:https://developer.aliyun.com/learning/roadmap/serverless