Cloud Service Engine,簡稱CSE,是中間件部門研發的面向通用Serverless計算的中間件產品,目標是具備AWS Lambda的各種優勢,同時可以解決AWS Lambda的關鍵技術缺陷。

AWS Lambda如果用於核心業務,可能會有以下缺陷:(僅代表個人觀點)

  • 要求用戶以Function為單位開發,全新的開發框架,雲廠商強綁定。社區主流技術棧遷移成本高。
  • Function啟動速度要足夠快,毫秒級或者秒級,這個限制對適用場景有很強的約束。
  • Function之間的調用通過API Gateway,響應時間更長。

CSE目前在集團內測中,本文非完整產品介紹,Serverless話題涉及範圍極廣,幾乎包含了代碼管理測試發布運維擴容等與應用生命週期關聯的所有環節。本文主要回答個人在探索這個方向時的思考以及中間件部門正在做的解決方案,目標是儘可能讓開發者少改代碼,甚至不改代碼,就能具備AWS Lambda的技術優勢。

我認為的Serverless是什麼?

AWS對Serverless的定義

以上觀點來自AWS官網 鏈接

AWS 定義的Serverless包含了哪些功能項

個人的補充觀點

個人對Serverless的觀點僅在AWS上補充,AWS的整個方案非常完善,但是沒有解決存量應用如何遷移到Serverless架構,僅僅針對新開發的應用,建議用戶用FaaS方式開發,纔有機會變成Serverless架構。

要將Serverless架構大規模推廣,必須要能有針對存量業務的解決方案。

Serverless在雲計算中的位置是什麼?

雲計算歸根結底是一種IT服務提供模式,不論是公共雲還是專有雲(以IT設備的歸屬不同分類),其本質都是IT的最終使用者可以隨時隨地並且簡便快速地獲取IT服務,並以獲取服務的層次分為IaaS、PaaS、SaaS。目前看IaaS、PaaS都已經做到了按需付費。PaaS甚至做到了按請求付費,如DB,CACHE,MQ等,但是IaaS的付費粒度仍然是時間維度,最快按照小時付費,按照分鐘來交付。

基於以上現狀,應用的開發維護方式相比傳統IDC模式的開發維護差別還不是很大,而AWS Lambda提供了一種全新的方式,只需要用戶寫業務代碼,提交到雲上,所有和機器容量,可用性,機器為單位的運維工作全部交給了雲平臺,這種模式極大的放大了雲的彈性價值,真正做到了按需付費。

本文試圖提供一種更規模化的解決方案,像AWS Lambda一樣,能繼續放大雲的彈性價值,並且是可以兼容存量應用。

現存在線業務演變成Serverless架構的關鍵挑戰是什麼?

當前的在線應用程序具有以下特點

  • 資源分配速度 = 分鐘級
  • 應用程序啟動速度 = 10分鐘+

基於以上客觀條件,通常做法是提前預定好機器數量來應對任意時刻的流量峯值,假設上述技術參數變為毫秒級,就有機會將應用程序架構演變成下圖所示方式。

上圖中Service A在調用Service B時,如果B的容量充足,調用成功,如果B容量不足,這時候可能是線程池滿,可能直接觸發限流閥值,A會收到一個錯誤碼,A會直接調用資源總控系統,資源總控系統負責新分配一個Service B實例,這個分配的速度非常快,耗時幾十毫秒,同時把B的服務地址直接返回給A,A將之前未完成的請求發送到新創建的Service B。

以上過程對於開發者完全透明,具備了以下價值:

  • 價值一:無需管理伺服器,意味著無需容量評估,容量評估這件事情對於應用負責人一直是一個極難解的問題,因為我們很難預測未來的峯值是什麼。
  • 價值二:持續擴展,之前的做法是每個應用程序獨佔一定數量的資源,如果變成Serverless模式,意味著所有應用程序共享資源池,也意味著每個應用程序幾乎可以無限擴展。
  • 價值三:按照請求計費,因為每個實例的啟動時間甚至比FaaS的函數啟動時間還快,就可以像FaaS一樣來覈算成本,成本只與以下因素有關
    • 請求數量(QPS)
    • 每次請求CPU執行時間,例如100ms
    • 每個實例的內存規格

綜上所述:為了做到以上描述的分散式架構,關鍵技術點在於應用啟動速度,這裡的應用啟動速度是指應用可以正常處理流量為止。

如何將應用啟動速度加速到毫秒級?

應用在啟動過程中通常會初始化多個組件,如各種中間件,各種數據結構,以及網路調用外部服務,在阿里內部廣泛推廣SOA,微服務情況下,會大量載入共享業務SDK,會存在啟動過程達到10分鐘量級的情況,個別應用可能會更長。

因此,這個啟動過程必須提前完成,纔有機會臨陣磨槍的方式去創建新實例。

方案一:應用冷啟動資源壓縮方案

L1彈性能力是指在一臺物理機或者大規格的ECS上部署同一個應用的多個實例,通過操作系統和JVM的優化,一個佔用4G堆內存的應用,即使部署10份,僅需佔用2.2G RAM。以線上菜鳥生產應用為例。

L1總結來看是一種高密度部署方式,由於應用已經提前啟動,並且對容器進行凍結,意味著這個應用實例CPU佔用率為0,RAM佔用相當於之前的1/20,但是具備了毫秒級彈性的能力。L1的特點是啟動速度極快,但是需要消耗資源,且只能垂直彈性。

L2是通過將應用程序啟動後在RAM中的指令和數據結構 dump到磁碟文件,只需要在機器之間拷貝文件即可以達到橫向彈性的能力,這個時間消耗主要是數據的網路傳輸時間+內存拷貝時間,大約在5秒左右可以完成。L2的成本開銷只有網路磁碟容量,開銷極低,可忽略不計。

L2的每個SNAOSHOT對應一個可運行的實例,例如預計一個應用需要最大啟動100個實例,那麼需要提前生成100個SNAOSHOT,每個SNAOSHOT對應一個運行實例,需要啟動時,從遠程磁碟載入這個SNAPSHOT。

此方案通過L1和L2的組合來達到加速應用啟動的目的,在支持一定流量脈衝能力下,可以最大50ms內啟動任意應用,平均在10ms內完成。

方案二:應用熱複製啟動加速方案

L1採用通過fork種子進程達到快速啟動的效果,操作系統團隊專門為此開發了fork2技術,與linux native fork的關鍵區別是可以指定PID來fork一個進程

pid_t fork2(pid_t pid);

L2的單個SNAPSHOT可以創建多個進程,一對多關係。

自研兩種方案對比

  • 方案二:會存在UUID問題,如開發者希望應用每個實例啟動都賦值一個UUID給一個靜態變數,而通過fork會導致每個實例的這個靜態變數都相同,與開發者預期不符。優勢是整個方案更易實現,語言無關,成本效果更優。

適合FaaS、盒馬NBF這類場景或者開發者自己定義開發框架,能避免UUID這種情況的 場景使用。

  • 方案一:不存在UUID問題,但是每種語言的VM要單獨定製,成本效果相比方案二略差。

整體來看,方案一的適用場景更廣,但是實現成本更高,方案二較適合FaaS,NBF這類場景。

與AWS Lambda方案對比

Lambda為了做到快速擴縮容,要求用戶的應用以Function為單位開發,Lambda Runtime動態載入Function來快速增加實例。

CSE通過將一個應用的多個實例啟動後,共享相同的指令數據,抽取出不同的指令數據,每次啟動實例只需要載入多實例的差異部分。因此可以透明兼容社區主流技術棧,如Spring Boot,PHP/Java/Python/NodeJS等。

CSE的成本優勢

理論模型

Serverless方式應用佔用的實例數隨時在變化,因此可以多個應用錯峯使用同一臺機器。

量化分析

Serverless的成本優勢是可以和CPU Share&離在線混部等調度技術的成本優勢做疊加,能給最終用戶一個更優的總體成本。

CSE的代碼樣例

HSF demo

package com.test.pandora.hsf;

import com.alibaba.boot.hsf.annotation.HSFProvider;

@HSFProvider(serviceInterface = HelloWorldService.class)
public class HelloWorldServiceImpl implements HelloWorldService {
@Override
public String sayHello(String name) {
return "hello : " + name;
}
}

Spring Boot demo

package com.example.java.gettingstarted;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class HelloworldApplication {
@RequestMapping("/")
public String home() {
return "Hello World!";
}

@RequestMapping("/health")
public String healthy() {
// Message body required though ignored
return "Still surviving.";
}

public static void main(String[] args) {
SpringApplication.run(HelloworldApplication.class, args);
}
}

CSE的成功案例

  • 盒馬p0級服務,文描在雙十二場景驗證中,機器數量從11臺到2臺(2~10臺之間波動)。

3.8女王節的最新數據,盒馬導購域的P0級服務流量峯值從4000+瞬間飆到12萬,CSE瞬間彈性擴容,從2臺-->5臺-->10臺,流量峯值回落後又縮容到2臺。

  • 盒馬p0級服務,天氣在雙十二場景驗證中,機器數量從4臺到2臺(2~10臺之間波動)。
  • 1688的buyer-tools應用,之前固定4臺機器,serverless化完成後,機器數量變成1臺(1~4臺之間波動)。預發可實現0 ~ 1臺實例之間波動。

CSE的約束和限制

  • 高脈衝型流量業務消耗的成本會更高。
  • 應用儘可能避免後臺活動線程的CPU消耗。
  • 應用儘可能無狀態。
  • 應用儘可能使用短連接,長鏈接要能支持斷線毫秒級重連能力。

CSE引用了以下合作團隊的代碼,特此致謝。

  • 使用了操作系統團隊開發的 fork2技術,感謝 @啟翾 @喻望 @笑哲
  • 使用了JVM團隊開發的 APPCDS技術,感謝 @三紅 @傳勝 @QI, Yumin @在弦
  • 姬風團隊幫助優化了中間件SDK啟動速度,感謝 @姬風以及他的團隊同學
  • Pouch團隊做了大量容器適配Serverless的優化,感謝 @華敏 @沈凌

本文作者:王小瑞

原文鏈接

更多技術乾貨敬請關注云棲社區知乎機構號:阿里云云棲社區 - 知乎

本文為雲棲社區原創內容,未經允許不得轉載。

推薦閱讀:

相關文章