基于Serverless的云原生转型实践
作者:計緣,阿里云解決方案架構師
云原生架構是什么
回顧過去十年,數字化轉型驅動著技術創新和商業元素的不斷融合和重構,可以說,現在已經不是由商業模式決定采用何種技術架構,而是由技術架構決定企業的商業模式。所以無論是行業巨頭還是中小微企業都面臨著數字化轉型帶來的未知機遇和挑戰。機遇是商業模式的創新,挑戰來自對整體技術架構的變革。
新一代的技術架構是什么?如何變革?是很多互聯網企業面臨的問題。而云原生架構則是這個問題最好的答案,因為云原生架構對云計算服務方式與互聯網架構進行整體性升級,深刻改變著整個商業世界的 IT 根基。
雖然云原生的概念由來已久,很多人并不理解什么是云原生。從技術的角度來講,云原生架構是基于云原生技術的一組架構原則和設計模式的集合,旨在將云應用中的非業務代碼部分進行最大化的剝離,從而讓云設施接管應用中原有的大量非功能特性(如彈性、韌性、安全、 可觀測性、灰度等),使業務不再受非功能性業務中斷困擾的同時,具備輕量、敏捷、高度自動化的特點。簡單的說,就是幫助企業的業務功能迭代更快、系統能承受住各種量級的流量沖擊的同時,構建系統的成本更低。
傳統架構與云原生架構的區別
上圖展示了在代碼中通常包括的三部分內容,即業務代碼、第三方軟件、處理非功能特性的代碼。其中“業務代碼”指實現業務邏輯的代碼。“三方軟件”是業務代碼中依賴的所有三方庫,包括業務庫和基礎庫。“處理非功能性的代碼”指實現高可用、安全、可觀測性等非功能性能力的代碼。
這三部分中只有業務代碼是對業務真正帶來價值的,另外兩個部分都只算附屬物,但隨著軟件規模的增大、業務模塊規模變大、部署環境增多、分布式復雜性增強,使得今天的軟件構建變得越來越復雜,對開發人員的技能要求也越來越高。云原生架構相比較傳統架構前進了一大步,即從業務代碼中剝離了大量非功能性特性到 IaaS 和 PaaS 中,從而減少業務代碼開發人員的技術關注范圍,通過云服務的專業性提升應用的非功能性能力。
這便是云原生架構的核心思路。
為什么需要云原生架構
解釋完什么是云原生架構后,大家可能會有進一步的思考,即當今互聯網企業為什么需要云原生架構。分析下SaaS的市場規模可以發現,2019年SaaS市場規模為360億元,2020年仍保持可觀上漲趨勢,2022年SaaS市場規模預計破千億。
縱觀中國企業級SaaS行業發展歷程,大體分為四個階段:2015年之前,中國市場和絕大多數中國企業對“什么是SaaS”缺乏基本認知,基于私有部署的傳統軟件形式仍為主流,企業級SaaS市場方興未艾。到了2015年,隨著云計算技術的進一步成熟,中國企業級SaaS行業進入快速成長階段,這個慢賽道逐漸為公眾所知。
時至今日,在疫情、經濟、社會環境的大背景下。互聯網企業開始尋求新的商業模式,一些抓住機會的SaaS企業實現了快速響應,結果是其業務呈現成倍增長,比如:
- 餐飲SaaS廠商幫助線下餐飲門店開發小程序點餐系統,實現無接觸點餐。
- 電商零售領域的ERP廠商幫助企業建立會員管 理系統。
- 營銷SaaS廠商通過流量平臺幫助企業在線營銷,遠程觸達客戶。
所以,在“如何活下去”成為熱門議題的背景下,快速響應能力成為企業之間的核心競爭優勢,SaaS企業需要及時滿足市場的新需求。而這正是前幾年中國SaaS企業為了快速占領市場、盲目跟風、一味借鑒國外產品所產生的天生缺陷。為彌補這些缺陷,SaaS廠商需要根據市場的需求快速調整產品服務方向,業務功能要多元化,業務體系需要新的枝杈,在技術上也有更大的挑戰。
除了市場帶來的壓力,SaaS企業自身也有諸多痛點:
- 大多SaaS產品只做所謂的通用能力,或者只是一味模仿國外產品,一旦深入到行業屬性比較重的場景時便無法滿足需求,所以被貼上了“半成品”的標簽,導致市場接受程度不如預期。
- 產品模塊單一、功能相似的SaaS產品很容易陷入價格競爭,最后只能以虧損獲得網絡效應,但會終食惡果。
- 市場對SaaS產品的定制化需求過多,使得SaaS企業缺乏對產品打磨的精力,把一個SaaS型公司做成了項目型公司。
SaaS企業解決以上的外憂內患的核心就是專注在業務。要做好一款SaaS產品,對于業務渠道、競爭格局、用戶體驗等諸多方面都有更加嚴苛的要求,甚至從市場運營、產品經理到研發、運維都要專注在業務,所有這些角色的本職工作都應該為行業業務服務,行業的深度分析,快速響應市場,穩定的產品質量這些是必須要具備的。但這就要求技術具備更快的迭代速度,業務推出速度從按周提升到按小時,每月上線業務量從“幾十 / 月”提升到“幾百 / 天”,并且不可接受業務中斷。
另一個互聯網企業需要云原生轉型的原因是中國的劉易斯拐點已經到來。劉易斯拐點,即勞動力過剩向短缺的轉折點,是指在工業化進程中,隨著農村富余勞動力向非農產業的逐步轉移,農村富余勞動力逐漸減少,最終達到瓶頸狀態。用大白話說就是中國的人口紅利已經逐漸消退,企業勞動力成本不斷增加,加上2020年疫情的影響,成本因素越來越成為企業的重要考量。而SaaS產品訂閱制付費、通用性強、低部署成本的特點,便成了企業降本增效的新選擇。這是SaaS企業在市場中的機會,而且對于SaaS企業本身來說,同樣有降本增效的需求,而且內部降本增效做得越好,SaaS產品在市場上的競爭力會更加明顯。
以上這些現狀的解法和云原生架構和核心能力不謀而合:
- 云原生將三方軟件和非功能性能力的完全兜底,可以極大程度解放企業研發、運維人員的精力,并使其可以專注在業務上。
- 系統的橫向擴展性、高可用性、健壯性、SLA由云原生架構兜底,解決了SaaS產品最忌諱的穩定性問題。
- 將一些自建的組件遷移至云原生架構中,對傳統的部署方式和資源進行云原生化,GitOps的落地,在資源成本和人力成本方面都有進一步的優化。
如何落地云原生架構
在聊如何落地云原生架構之前,我們先來看一看云原生架構成熟度模型(SESORA):
云原生架構成熟度模型
云原生架構成熟度模型有六個評判維度,可以將成熟度劃分為4個級別。我會從自動化能力、無服務化能力、彈性能力、可觀測性、韌性能力這五個維度,貫穿說明如何落地云原生架構。
傳統架構
上圖展示的是一個較傳統的Java+SpringCloud架構應用服務側的部署架構。除了SLB,基本上所有的組件都部署在ECS上。下面我們來一起看看如何將這個架構轉型為云原生架構。
無服務化(Serverless)
Serverless的概念是什么在這篇文章不在贅述,可以參閱這篇文章進行了解。使用ECS集群部署服務的架構有兩個顯著的短板:
- 運維成本高:ECS的各項狀態、高可用都需要運維同學維護。
- 彈性能力不足:每次有大促活動時,都需要提前購買ECS,擴展服務的節點數,然后再釋放,并且這種情況只適用于定時定點的活動,如果是不定時的流量脈沖則無法應對。
所以首先我們要將服務的部署方式Serverless化,我們可以選擇Serverless App Engine(SAE)作為服務應用的發布、部署平臺。SAE是面向應用的Serverless PaaS平臺,能夠幫助用戶免運維IaaS、按需使用、按量計費,做到低門檻服務應用云原生化,并且支持多種語言和高彈性能力。
命名空間
打開SAE控制臺,我們首先創建命名空間,SAE的命名空間可以將其下的應用進行網絡和資源的邏輯隔離,通常我們可使用命名空間來區分開發環境、測試環境、預發環境、生產環境。
創建應用
創建好命名空間后,我們進入應用列表,即可選擇不同的命名空間,看到其下的應用或者創建應用:
選擇對應的命名空間,然后創建應用:
- 應用名稱:服務名稱,用戶自行輸入。
- 專有網絡配置:
- 自動配置:自動幫用戶配置VPC、Vswitch、安全組。這些組件都會新創建。
- 自定義配置:用戶選擇命名空間,VPC,VSwitch以及安全組。一般選擇自定義配置,因為咱們的服務所屬的VPC肯定要和其他云資源的VPC是相同的,這樣才能保證網絡暢通。這里需要注意的一點是,當在新的命名空間下第一次創建好應用后,該命名空間就會和所選的VPC進行綁定,之后再創建應用時,該命名空間對應的VPC不可更改。如果需要更改,可以進入命名空間詳情進行更改。
- 應用實例數:應用(服務)節點數量,這里的節點數量按需設置,而且不是最終設定,因為后續可以手動或者自動的擴縮節點數。
- VCPU/內存:該應用在運行過程中需要的CPU和內存的規格。這里的規格是單個實例數的規格。既如果選擇了2C4G,那么有2個實例的話,就是4C8G。
配置完基本信息后,下一步進入應用部署配置:
- 技術棧語言:Java語言支持鏡像、War包、Jar包三種部署方式,其他語言支持鏡像部署方式。以Java Jar包方式為例:
- 應用運行環境:默認標準Java應用運行環境即可。
- Java環境:目前支持JDK7和JDK8。
- 文件上傳方式:支持手動上傳Jar包或者配置可以下載Jar包的地址。
- 版本:支持時間戳和手動輸入。
- 啟動命令設置:配置JVM參數。
- 環境變量設置:設置容器環境中的一些變量,便于應用部署后靈活的變更容器配置。
- Host綁定設置:設置Host綁定,便于通過域名訪問應用。
- 應用健康檢查設置:用于判斷容器和用戶業務是否正常運行。
- 應用生命周期管理設置:容器側的生命周期腳本定義,管理應用在容器在運行前和關閉前的一些動作,比如環境準備、優雅下線等。
- 日志收集服務:和SLS日志服務集成,統一管理日志。
- 持久化存儲:綁定NAS。
- 配置管理:通過掛載配置文件的方式向容器中注入配置信息。
我使用Jar包的方式部署完應用后,在對應命名空間下就可以看到剛剛創建的應用了:
點擊應用名稱可以查看應用詳情:
綁定SLB
因為ServiceA在架構中是對外提供接口的服務,所以需要對該服務綁定公網SLB暴露IP和做負載均衡,在SAE中,綁定SLB非常簡單,在詳情頁中,即可看到應用訪問設置:
添加SLB時可以選擇新建也可以選擇已經創建好的SLB:
服務/配置中心
對于微服務架構,服務中心和配置中心是必不可少的,大家常用到一般是Nacos、Eureka、ZooKeeper三種。對于云原生架構來講,根據不同的場景,服務/配置中心可以有以下幾種選擇:
對于現狀就是使用Nacos的客戶而言,轉型云原生架構,服務/配置中心如上面表格所示有兩種選擇:
- 需要快速轉型,對服務/配置中心高可用要求不是特別極致的情況下,建議直接使用SAE自帶的Nacos即可,代碼不需要做改動,直接在SAE中創建應用即可。SAE控制臺提供的配置管理在界面操作和功能上和開源Nacos的控制臺基本一致。
- 對服務/配置中心高可用要求比較高的情況下,建議使用MSE Nacos,它的優勢是獨享集群,并且節點規格和節點數量可以根據實際情況動態的進行調整。唯一不足的一點就是需要修改Nacos的接入點,算是有一點代碼侵入。
對于現狀是使用Eureka和ZooKeeper的客戶而言,建議直接使用MSE Eureka和MSE ZooKeeper。
這里我簡單介紹一下MSE。微服務引擎MSE(Microservice Engine)是一個面向業界主流開源微服務框架Spring Cloud和Dubbo一站式微服務平臺,提供治理中心、托管的注冊中心和托管的配置中心。這里我們用到的是MSE的托管注冊中心和托管配置中心。
MSE有三塊核心的功能點:
- 支持三大主流服務中心,節點規格和數量靈活搭配,可在運行時動態調整節點規格/數量。
- 通過命名空間邏輯隔離不同環境。
- 配置變更實時推送并且可追蹤。
彈性能力(Elasticity)
云原生架構成熟度模型中的彈性能力同樣依托于SAE來實現,因為Serverless的底層實現原理,所以在SAE中的應用實例數(節點數)擴縮速度非常快,可達到秒級。
進入應用詳情頁的實例部署信息,可以看到應用的具體實例:
SAE提供了兩種擴縮應用實例數的方式,手動方式和自動方式。
手動擴縮
在控制臺右上方有手動擴縮操作按鈕,然后選擇要擴縮到的實例數即可:
當進行擴縮時,我們可以看到具體實例的變更狀態:
自動擴縮
在控制臺右上角有自動擴縮操作按鈕,然后可以看到創建擴縮規則的界面。SAE自動擴縮提供時間策略和指標策略兩種。
上圖是時間策略,即設置好具體的時間節點,在這個時間節點要將應用的實例數擴到幾個或者縮到幾個。這種策略適合流量高峰期有相對明確時間節點的場景,比如在線教育的客戶,通常流量高峰在晚上8點開始,11點逐漸結束,這種情況下,通過定時策略在7點半左右把應用的實例數擴起來,然后11點之后逐漸把應用實例數縮回正常。
上圖是指標策略,目前提供CPU使用率、內存使用率、應用的QPS閥值、應用接口平均響應時間(RT)閥值四種指標,這四種指標可以配合使用。當這四種指標其中有一種達到閥值后就會觸發擴容,會對應用實例進行逐漸擴容。當指標小于閥值后觸發縮容。這種策略適合流量高峰時間不固定的場景,比如市場營銷,游戲運營。
成本優化
對于彈性能力,大家可能更多的是關注它能讓系統快速支撐流量脈沖,增加系統橫向擴展的能力。其實因為SAE有極致的彈性能力,再加上按分鐘、按量計費的模式,對整體的資源成本是有一定優化的。
可觀測性(Observability)
應用側的可觀測性分兩個維度,一是縱向的Metrics指標,比如主機的CPU、內存、磁盤各項指標,Pod的CPU、內存各項指標,JVM的Full GC、堆內存、非堆內存各項指標。另一個維度是橫向的請求調用鏈路監測,上游服務到下游服務的調用、上游接口到下游接口的調用。
在監控微服務架構時,通常需要從三個角度來看:
- 應用的整體健康狀況。
- 應用每個實例的健康狀況。
- 應用每個接口的健康狀況。
而SAE對應用的監控也都覆蓋了上述這兩個維度和三個角度。
應用整體健康狀況
進入應用詳情頁,點擊左側菜單中的應用監控/應用總覽,便可以看到應用的整體狀況:
- 總請求量:可以一目了然的看到請求量是否明顯的異常,比如驟降或者陡升。
- 平均響應時間:應用整體接口的平均響應時間,這個指標直接反映最真實的應用健康狀況。
- Full GC:JVM里比較重要的指標,也是會直接影響系統性能的因素。
- 慢SQL:智能抓取執行時間大于500ms的SQL。
- 一些曲線視圖:幫助我們掌握不同時段的應用情況。
應用實例節點健康狀況
進入應用詳情頁,點擊左側菜單中的應用監控/應用詳情,便可以看到應用每個節點的信息:
從上圖可以看到,左側會列出當前應用的所有實例節點,包括該節點的平均響應時間、請求次數、錯誤數、異常數。如果我們按照影響時間降序排序,比較靠上的節點就是響應時間較慢的節點,然后我們就需要分析是什么原因導致這些節點的響應時間較慢。所以,右側會提供了一些檢查維度來幫助我們分析排查問題。
比如查看JVM指標:
應用接口健康狀況
進入應用詳情頁,點擊左側菜單中的應用監控/接口調用,便可以看到應用每個接口的信息:
接口監控和應用實例節點監控的思路一致,左側會列出所有請求過的接口,同樣顯示了響應時間、請求數、錯誤數,右側同樣提供了一些檢查維度來幫助我們分析接口RT高的原因。
比如查看SQL調用分析:
縱向Metrics指標
在上述三個角度中,其實已經涵蓋了絕大多數Metrics指標,比如有應用健康狀態的指標、JVM的指標、SQL指標、NoSQL指標等。
橫向調用鏈路
在很多時候,我們單純的看Metrics指標是無法確定問題的根本原因的,因為會涉及到不同服務之間的調用,不同接口之間的調用,所以需要查看服務和服務之間、接口和接口之間的調用關系以及具體的代碼信息。在這個維度上,SAE集成的ARMS的監控能力便可以實現。我們在應用監控/接口調用/接口快照中可以看到有請求的接口快照,通過TraceID便可以查看該接口的整體調用鏈路:
從上面這個圖我們可以看出很多信息:
- 該接口在服務級別的完整請求鏈路,比如ikf(前端)-> ikf-web(java服務)-> ikf-blog(java服務)-> ikf-blog(java服務)
- 每個服務的狀態情況,比如狀態一列是紅點,說明在這個環節是有異常出現的。
- 在每個服務中請求的接口名稱。
- 每個服務的請求耗時。
除了上述這些顯性的信息以外,還有一些隱性的信息:
- 上游服務ikf-web的總耗時是2008ms,但下游服務ikf-blog的總耗時是5052ms,而且耗時起點是一樣的,說明ikf-web到ikf-blog是一個異步調用。
- 既然ikf-web到ikf-blog是異步調用,然而ikf-web的耗時有2s之多,說明ikf-web服務中的接口也有問題。
- 在ikf-blog服務中,又有內部接口被調用,因為從調用鏈上出現了兩個ikf-blog,并且這個內部調用是同步調用,而且問題出現在最后一個接口調用上。
從以上這些信息可以幫我們縮小和圈定問題根因出現在哪個環節的范圍,然后我們可以點擊方法棧一列的放大鏡,查看具體的方法棧代碼信息:
從方法棧這里我們又可以得到很多顯性信息:
- 具體的方法。
- 每個方法的耗時。
- 方法產生的具體異常信息。
- 數據庫操作的具體SQL語句,甚至SQL上的Binding Value。
當然除了顯性信息外,還有一個比較重要的隱性信息,比如我們可以看到BlogController.findBlogByIsSelection(int isSelection)這個方法的耗時是5s,但是該方法內部的數據庫操作的耗時很少,只有1ms,說明耗時是屬于業務代碼的,畢竟業務代碼我們是抓不到也不會去抓取信息的。這時我們可以有兩種方式去定位具體問題:
- 從方法棧信息中已經知道了具體的服務和具體的方法,那么直接打開IDE查看、分析代碼。
- 查看方法棧頁簽旁邊的線程剖析,也基本可以確定問題所在。比如上圖這個情況,我們查看線程剖析后會發現他的耗時是因為java.lang.Thread.sleep( ):-2 [3000ms]。
韌性能力(Resilience)
對于云原生架構的韌性能力,我會從優雅上下線、多AZ部署、限流降級三個方面來聊一聊。
優雅上下線
一個好的產品,要能快速應對用戶對產品功能、能力具有普適性的反饋和意見,能快速響應市場需求的變化。那么產品的功能就需要快速的做迭代和優化,從IT層面來看,就是要有快速、高效、高質量的發布變更流程,能夠隨時進行生產環境的服務發布。
但是這會帶來一個核心問題,即頻繁的服務發布,并且不能影響用戶體驗,用戶的請求不能斷流。所以這就要求我們的系統部署架構中有優雅上下線的能力。
以微服務架構來說明,雖然開源的產品有能力和方案做到近似優雅上下線,但也是近似做到,當發布服務節點較多的情況下依然會有斷流的情況。所以開源方案有諸多問題:
- 注冊中心不可靠、通知不及時。
- 客戶端輪訓不實時、客戶端緩存。
- 自定義鏡像非1號進程,Sigterm信號無法傳遞。
- 無默認優雅下線方案,需要添加actuator組建。
在無服務化/服務配置中心章節中,我闡述了SAE自帶的服務中心和MSE的服務中心,無論使用那種方案,我們都對優雅上下線做了進一步的優化。
從上圖可以看到,部署在SAE的應用具有主動通知服務中心和服務消費者的能力,再結合Liveness應用實例探活和Readiness應用業務探活的機制,能讓我們的服務在進行部署和因為其他原因掛掉時不會影響用戶的正常訪問。
多AZ部署
本著雞蛋不能放在一個籃子里的原則,一個應用的多個節點,應該分布在不同的可用區,這樣整體應用的高可用和健壯性才是足夠好的。SAE支持設置多個交換機(VSwitch),每個交換機可以在不同的可用區,這樣在部署、擴容應用的節點時會隨機從可選的可用區拉起實例:
這就避免了當某個可用區出現問題掛掉時,整體系統因為在一個可用區而掛掉,這也是最基本的同城多活的實踐。
限流降級
限流降級是系統斷臂求生的能力,在遇到突發的流量脈沖時,可以及時限制流量,避免整個系統被擊穿,或者當流量超出預期時,及時切斷非核心業務,釋放資源來支撐核心業務。
目前對于Java應用,SAE也支持限流降級的能力,首先對應用的所有接口的請求指標進行抓取和監控:
然后我們可以針對每一個接口設置流控、隔離、熔斷的規則,比如我對/checkHealth接口設置一條流控規則:
當該接口的QPS達到50后,單個機器超過50的請求將快速失敗。比如我們對一個有6個節點的應用進行壓測時,可以看到每個節點的QPS情況:
當開啟流控規則后,可以立即看到限流的效果:
可以看到QPS被精準的控制到50,超過50的請求直接返回失敗。
自動化能力(Automation)
在自動化能力方面,我主要從CICD流程這個維度來聊一聊。大家從上面章節的截圖可以看到,有很多是SAE控制臺的截圖,在實際應用中肯定不會通過控制臺來一個一個發布應用,必然都是通過CICD流程來做自動化的應用打包和發布流程。
SAE在這個方面提供兩種實現自動化運維的方式。
基于Gitlab和Jenkins
目前很多企業的CICD流程都是基于Gitlab和Jenkins來做的,那么SAE也支持將發布的操作集成到這種方案里。這個方案的核心是SAE會提供一個Maven插件,同時對應有三個配置文件,Maven插件通過這三個配置文件中的信息將打包好的Jar/War或者鏡像發布到對應的SAE應用中。
- toolkit_profile.yaml:配置RegionID、AccessKey ID、AccessKey Secret。
- toolkit_package.yaml:配置比如應用部署包類型、部署包地址、鏡像地址。
- toolkit_deploy.yaml:配置比如SAE應用的ID、應用所屬命名空間ID、應用名稱、發布方式等。
更詳細的配置信息可以參閱該文檔。
然后在Jenkins的任務中,對Maven設置如下的命令即可:
clean package toolkit:deploy -Dtoolkit_profile=toolkit_profile.yaml -Dtoolkit_package=toolkit_package.yaml -Dtoolkit_deploy=toolkit_deploy.yaml這樣就可以很容易的將SAE的部署流程集成到基于Gitlab和Jenkins的CICD方案里了。
基于Open API
還有一些企業會自己研發運維平臺,運維賦能研發,由研發同學在運維平臺上進行運維操作。面對這種場景,SAE提供了豐富的Open API,可以將SAE控制臺上90%的能力通過Open API集成到客戶自己的運維平臺中。詳細的OpenAPI說明可以參與該文檔。
總結
基于SAE武裝過系統后,整體的部署架構會變成這樣:
云原生架構成熟度模型(SESORA)在我闡述的這五個維度一共是15分,基于SAE的云原生架構在這五個維度會達到12分:
- 無服務化:3分
- 彈性能力:3分
- 可觀測性:2分
- 韌性能力:2分
- 自動化能力:2分
對于上手、實踐、落地快捷簡單,又能達到比較好的云原生架構成熟度的SAE方案,大家還在等什么呢?一起實踐起來吧。如果大家有任何問題,可以加入釘釘群:35712134來尋找答案,我們不見不散!
原文鏈接:https://developer.aliyun.com/article/782503?
版權聲明:本文內容由阿里云實名注冊用戶自發貢獻,版權歸原作者所有,阿里云開發者社區不擁有其著作權,亦不承擔相應法律責任。具體規則請查看《阿里云開發者社區用戶服務協議》和《阿里云開發者社區知識產權保護指引》。如果您發現本社區中有涉嫌抄襲的內容,填寫侵權投訴表單進行舉報,一經查實,本社區將立刻刪除涉嫌侵權內容。總結
以上是生活随笔為你收集整理的基于Serverless的云原生转型实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 云通信产品运营带你玩转号码隐私保护
- 下一篇: 尼日利亚学生开发者,用阿里云PAI打造了