Serverless 時代下微服務應用全託管解決方案

語言: CN / TW / HK

作者:陳昕

Serverless 時代下微服務發展與挑戰

1.png

早期業務規模比較簡單,大多團隊開發採用單體應用,已經能夠很好地滿足團隊的業務需求,並且能夠快速迭代。但隨著業務規模的不斷增長,系統變得越來越複雜,單體應用逐漸無法滿足線上生產的問題。比如電商業務中,如果將交易、支付,商品等所有功能都集中在單體應用中開發,有可能會出現釋出簡單商品功能影響到交易,從而對整個電商系統產生影響,給企業造成損失。

這個時候很多團隊會把單體應用架構改為微服務的架構,解決單體應用的問題。但隨著業務進一步發展,系統愈加複雜,加之新技術的到來,比如雲原生時代下成了標準的 K8s 以及 容器映象 Docker 等,研發運維投入會越來越大,需要保證幾十甚至幾百個服務正常執行與協作,這給運維帶來了很大的挑戰:

2.png

1、效率:隨著應用規模的擴張,新的研發團隊需要面臨很多開發和測試中的複雜性問題。在團隊協作上,不同應用團隊之間如何更好地形成穩定的呼叫鏈路,在幾十,幾百甚至上千個應用的大規模場景裡如何進行呼叫鏈路上應用的快速部署和灰度。此外,如此多應用的流量的處理、呼叫鏈路的跟蹤和服務鑑權也非常影響效率。

2、穩定:微服務化之後,會出現呼叫鏈路上某核心應用出現問題,導致整體系統發生雪崩,而且有時缺少視覺化、可觀測性的系統來幫助快速定位分析問題,導致難以快速定位到出現問題的應用,造成長時間的損失;

3、成本:單體應用一般只需部署幾臺機器;到了微服務時代,隨著應用數的劇增,出於可用性的考慮需要為每個應用保持一些冗餘,比如一次大促中,一個呼叫鏈路會涉及到十幾個應用,為了穩定性以及呼叫鏈路的安全,會進行整個鏈路應用的擴容,而實際上很多應用可能長時間沒有流量,伺服器空閒,導致巨大的成本浪費。 

面對微服務帶來的這些問題和需求, Serverless 應用引擎在這方面都做了哪些工作? 帶來哪些改變?

SAE 微服務應用全託管解決方案介紹

3.png

SAE 是面向微服務應用的 Serverless PaaS 平臺。作為雲平臺,它能夠為微服務應用進行全生命週期的託管。它能將 Serverless 和 K8s 本身的紅利集中在一起,讓微服務應用快速上線。以產品化的形式快速提供給使用者,開箱即用,解決使用者常見的微服務問題,提升研發效率。

4.png

SAE 提供了包含但不限於 CI/CD 流水線、微服務框架、 Spring Cloud、 Dubbo 、共享註冊中心、K8s 容器以及諸多運維相關的功能,包含呼叫鏈、日誌、告警、效能監控、流量的治理以及自動彈性等。它是 Serverless 框架與微服務進行深度結合的最佳實踐的平臺。

SAE 微服務功能和實踐

底層能力:微服務功能增強

5.png

在 Serverless 時代下,微服務的趨勢是客戶端越來越薄,其中與服務治理、業務邏輯無關的部分被沉澱在 Java agent 等元件裡,通過位元組碼的方式注入到業務中,對業務開發無侵入、無感知,並在過程中提供了豐富的微服務治理能力。比如流量管理相關的無損上下線、金絲雀釋出、視覺化資料上報等能力。

針對非 Java 場景,Java agent 也能夠與不同的微服務框架進行通訊。此外,與 Sidecar 之間的通訊也正在不斷完善建設中。

開發態實踐:端雲聯調

6.png

Serverless 應用引擎(SAE)基於 Alibaba CloudToolkit 外掛+ 跳板機可以實現:

  • 本地服務訂閱並註冊到雲端 SAE內建的註冊中心;
  • 本地服務可以和雲端 SAE 服務互相呼叫。 

在實現的時候使用者需要有一個 ECS 代理伺服器,實際註冊的是 ECS 代理伺服器到 SAE 的註冊中心,IDEA 在安裝 Cloudtoolkit 外掛以後,在啟動程序時,會在本地拉起一個通道服務,這個通道服務會連上 ECS 代理伺服器,本地所有的請求都會轉到 ECS 代理伺服器上,雲端對服務的呼叫也會通過 ECS 代理轉到本地,這樣就可以以最新的程式碼在本地斷點除錯,這就是雲端聯調的實現。

釋出態實踐:無損下線

在版本更換的過程中,SAE 是如何保證舊版本的微服務流量可以無損地下線掉?

7.png

上圖是微服務註冊和發行的整個流程,圖中有服務消費者和服務提供者,服務提供者分別有 B1、B2 兩臺例項,服務消費者分別有 A1、A2 兩臺例項。

B1、B2 把自己註冊到註冊中心,消費者從註冊中心重新整理服務列表,發現服務提供者 B1、B2,正常情況下,消費者開始呼叫 B1 或者 B2,服務提供者 B 需要釋出新版本,先對其中一個節點進行操作,如 B1,首先停止 Java 程序,服務停止過程又分為主動銷燬和被動銷燬,主動銷燬是準實時的,被動銷燬的時間由不同的註冊中心決定,最差的情況可能需要一分鐘。如果應用是正常停止,Spring Cloud 和 Dubbo 框架的 ShutdownHook 能正常被執行,這一步的耗時基本上是可以忽略不計的。

如果應用是非正常停止,比如說直接 Kill-9 的一個停止,或者是 Docker 映象構建的時候,Java 程序不是一號程序,且沒有把 Kill 訊號傳遞給應用的話,那麼服務提供者不會主動去登出節點,它會等待註冊中心去發現、被動地去感知服務下線的過程。

當微服務註冊中心感知到服務下線以後,會通知服務消費者其中一個服務節點已下線,這裡有兩種方式:註冊中心的推送和消費者的輪巡。註冊中心重新整理服務列表,感知到提供者已經下線一個節點,這一步對於 Dubbo 框架來說不存在,但對於 Spring Cloud 來說,它最差的重新整理時間是 30 秒。等消費者的服務列表更新以後,就不再呼叫下線節點 B。從第 2 步到第 6 步的過程中,註冊中心如果是 Eureka,最差的情況需要消耗兩分鐘;如果是 Nacos,最差的情況需要消耗 50 秒。

在這個時間內請求都有可能出現問題,所以釋出的時候會出現各種報錯。

8.png

經過上面的分析,在傳統的釋出流程中,客戶端有一個服務端呼叫報錯期,這是由於客戶端沒有及時感知到服務端下線的例項造成的,這種情況主要是因為服務提供者藉助微服務,通知消費者來更新服務提供的列表造成的。

9.png

那能否繞過註冊中心,服務提供者直接通知服務消費者?答案是肯定的。SAE 做了兩件事情,第一,服務提供者在應用釋出前,會主動向服務註冊中心登出應用,並將應用標記為已下線狀態,將原來停止程序階段的登出變成了 preStop 階段登出程序。

在接收到服務消費者的請求時,首先會正常處理本次請求,並且通知服務消費者此節點已經下線,在此之後消費者收到通知後,會立即重新整理自己的服務列表,在此之後服務消費者就不會再把請求發到服務提供者 B1 的例項上。 

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

執行態實踐:可觀測

10.png

執行態的例項,服務的執行過程中會出現這樣或者那樣的問題,怎麼去排查和解決它?

排查和解決的前提是必須具有強大的應用監控能力和診斷能力,SAE 集成了雲產品 ARMS,能夠讓跑在上面的 Java 微服務看到應用的呼叫關係拓撲圖,可以定位到你的 MySQL 慢服務方法的呼叫堆疊,進而定位到程式碼級別的問題。

比如一個請求響應慢,業務出現問題,它可以定位到是哪個請求、哪個服務、服務的哪行程式碼出現了問題,這樣就能為解決問題帶來很多便利。總的來說,就是我們要先有監控報警的能力,才能幫助我們更好地診斷服務運營過程中的問題。

客戶案例

11.png

總結

本文介紹了 Serverless 時代下微服務的發展以及過程中遇到的相對較複雜的需求,面對這些,阿里雲 Serverless 應用引擎 SAE 將“Serverless”的理念發揚到了極致,從最底層的 IaaS、到上層的 K8s、應用 PaaS、CICD、微服務套件整合、可觀測增強等等都做了“Serverless”化的託管,實現了 SAE 針對微服務場景的完整的解決方案。 

未來,SAE 會在微服務場景下做持續的能力增強,做出端到端的解決方案,降低開發者在面對微服務技術的時候的門檻,比如故障注入、全鏈路壓測,多語言微服務為等等;在 Serverless 場景下,其實是將複雜度由使用者交給了平臺,所以怎麼運維好這麼多應用也是我們的核心能力,我們會持續投入,不斷完善。