Categories
程式開發

支持多語言:Serverless雲函數如何解鎖語言限制?


導語 |雲函數Serverless Cloud Function(下文簡稱SCF)是騰訊雲為企業和開發者們提供的無服務器執行環境,幫助大家在無需購買和管理服務器的情況下運行代碼。 但是SCF 在使用過程中經常會受到開發語言方面的限制,造成拓展性和成本上的問題。 本文就將為大家介紹使用Custom Runtime 來解鎖SCF 語言限制,希望與大家一同交流。 文章作者:臧琳,騰訊雲Serverless研發工程師。

一、背景

SCF 作為騰訊雲FaaS 核心產品,支持javascript、python、php、java、go等多語言函數。 但是,在用戶實際使用過程中,我們發現了一些問題:

1. 尋求更多語言支持

我們時常會收到來自內外的各種關於編程語言的諮詢,比如SCF 是否支持dotnet、rust、deno 甚至C 等多種語言環境。

2. 關於現有語言的功能拓展

比如php 想要安裝更多的插件,就需要在執行環境中使用phpize 來安裝(因為部分插件可能和os library 等底層庫相關),但是雲函數因為安全等原因,限制了相關權限。

3. 關於Runtime的拓展性

舉個例子,現有SCF java 的語言環境是java8, 如果用戶想要在SCF 中使用JDK11 或者更新的JDK15,有沒有辦法解決呢?

4. 使用成本

目前,用戶如果想要在自己的業務代碼中嵌入SCF, 需要了解SCF 各個語言提供的入口函數及編程方法。 雖然我們已經盡量將使用方法和接口設計得簡單,但對於一些用戶來說,仍然要處理編程語言上的接口依賴,以及學習如何正確使用這些接口API。

5. 維護成本

簡單來說, 如果復用現有方案,給SCF 提供多語言支持其實是可行的,但是需要給每一種語言編寫一套使用SCF 的API。 這不僅僅需要SCF 研發同學懂得各種語言,還需要他們了解各個語言的安全特性,使用特性等,維護成本很高。

那麼, 有沒有一種方法能夠讓我們只需要維護一套統一的API,就能讓用戶從各種編程語言中解耦,還能解決上述列舉的各項問題呢? 答案就在於使用——Custom Runtime 。

二、Custom Runtime簡介

Custom Runtime(以下簡稱CR)使用方法較為簡單:CR 會暴露一套HTTP API 提供給用戶環境,而用戶只需要到特定端口上發送/接收HTTP 請求,即可以獲得SCF 下發的各種event,並返回處理結果。 具體的文檔可以參考:Custom Runtime 說明 [1] 。

總體來說,要使用Custom Runtime, 用戶需要做好以下準備:

1. bootstrap 可執行程序

此執行程序可以是任何形式的Linux 可執行文件,比如C 語言編譯出的二進製文件,或者是一個簡單的shell 腳本。

2. 用戶的事件處理函數

也就是通過CR 約定的HTTP API 實現event 的獲得和處理,以及結果返回。

3. 用戶語言Runtime(可選)

針對解釋型語言,或者是需要Runtime 來運行的語言,比如js、python、dotnet 等,需要用戶提供自己的Runtime,並在bootstrap 中提供相應的啟動Runtime 的命令。

騰訊雲官網上也提供了利用CR 實現shell 雲函數的示例[2],有興趣的小伙伴可以看看。

三、Custom Runtime 具體模型及用法示例

Custom Runtime 函數的內部處理流程如下所示:

支持多語言:Serverless雲函數如何解鎖語言限制? 1

目前Custom Runtime 的實現在SCF 側是一個HTTP Server 。 用戶側代碼作為HTTP Client 通過約定的API 給SCF 發請求來獲得事件及相關信息,並發送HTTP 請求返回處理結果給SCF 服務。

HTTP Server 端口號和URL,通過兩個環境變量傳遞到雲函數環境中:

SCF_RUNTIME_API:SCF_RUNTIME_API_PORT

HTTP API 定義如下圖所示:

支持多語言:Serverless雲函數如何解鎖語言限制? 2

1. 冷啟動階段(函數部署階段)

冷啟動階段主要是部署用戶代碼,完成用戶初始化,這個階段SCF 會在用戶提供的程序包(zip包)中尋找bootstrap 可執行程序,然後拉起該程序。 bootstrap 由用戶實現,內部啟動用戶代碼等工作。

用戶函數在冷啟動階段需要完成代碼初始化工作, 並通知SCF,初始化工作完成。 即發POST 到SCF_RUNTIME_API:SCF_RUNTIME_API_PORT/runtime/init/ready.

SCF 服務側接收用戶ready 的請求,初始化工作結束,通知上層服務。 函數進入調用流程(即event 此時可以下發到函數側)。

2. 熱啟動階段(調用階段)

函數通過GET SCF_RUNTIME_API:SCF_RUNTIME_API_PORT/runtime/invocation/next 獲得event 及相關ctx 信息。

SCF 在函數拉取event 之後, 等待用戶函數返回。

函數處理event 之後, 如正常返回,通過POST SCF_RUNTIME_API:SCF_RUNTIME_API_PORT/runtime/invocation/response 傳遞返回信息給SCF 服務。

如函數調用出現異常(此處指業務代碼需要返回錯誤信息), 則通過POST SCF_RUNTIME_API:SCF_RUNTIME_API_PORT/runtime/invocation/error 返回錯誤信息。

SCF 服務傳遞返回給上層服務,函數一次調用結束,進入下一次event 調用周期。

這裡我們用SCF 中CustomRuntime 的Deno 模板示例做說明,如下圖所示,程序包裡有:

支持多語言:Serverless雲函數如何解鎖語言限制? 3

  • bootstrap: 入口文件,這裡是shell, 可以看到紅線標註這一行就是啟動deno程序;
  • deno 二進制:Deno Runtime, 啟動deno 程序必須的launcher ;
  • demo.ts:用戶函數,裡面就實現了上面提到的和SCF 服務端交互的邏輯,也是用戶業務邏輯的主要處理函數。

bootstrap 主要是啟動demo.ts, 下面我們看看demo.ts 裡的代碼實現:

支持多語言:Serverless雲函數如何解鎖語言限制? 4

可以看到,主要是完成初始化階段。 下面再來看看調用是怎麼完成的:

支持多語言:Serverless雲函數如何解鎖語言限制? 5

可以看到,是通過GET (fetch) 循環拉取event, 然後調用processEvent() 來進行處理。 processEvent() 邏輯如下所示:

支持多語言:Serverless雲函數如何解鎖語言限制? 6

分別處理正常返回和錯誤返回。 最後再來看一下我們是怎麼封裝這裡的postData() 函數的:

支持多語言:Serverless雲函數如何解鎖語言限制? 7

以上就是一個Deno 函數使用SCF 的Custom Runtime 實現雲函數的全過程。

四、結語

從上文的論述我們不難看出:

1. SCF與語言無關

因為CR 的使用與語言無關,所以解鎖了SCF 的語言限制,也就是說只要可以實現一個HTTP Client,就可以通過HTTP API 的調用和SCF 進行交互,從而完成雲函數的事件處理及調用。

2. bootstrap 是入口

舉個例子,如果我用C 語言實現一個HTTP Client,按照CR 的約定完成與SCF 的交互,那麼完全可以編譯成一個名字叫bootstrap 的二進製文件,然後就可以跑C 的FaaS 函數了。

3. bootstrap可配置

用戶可以在bootstrap 裡面啟動多個進程,可以解鎖多種玩法,當然,要符合安全,畢竟用戶函數運行環境有安全限制。 但是,這已經可以解決一些“雲函數+agent進程”的需求。

4. 使用簡單

相對於學習各個語言的函數編寫規範,了解雲函數對各個語言的支持。 使用CR 只需要學習HTTP API 的使用即可。 更多的語言,環境相關的問題都是用戶在業務開發中使用到的,不需要額外學習。

Custom Runtime 剛剛上線, 已經得到了一些外網客戶的關注。 比如,有人用Custom Runtime 把Swift 放到了SCF 裡面,並做了相應的支持 [3] ;有人用Custom Runtime 在SCF 中跑了WASM, 並在上面做了Rust 語言的支持 [4] 。

還有很多類似場景,我們也在不斷的努力,引入更多的語言, 借助語言的生態,帶動Serverless的生態發展。 最後,歡迎大家體驗SCF Custom Runtime, 留下寶貴的意見!

參考資料

[1] Custom Runtime 說明 :

https://cloud.tencent.com/document/product/583/47274

[2] 官網示例 :

https://cloud.tencent.com/document/product/583/47610

[3] 場景拓展1:

https://github.com/stevapple/swift-tencent-scf-runtime

[4] 場景拓展2:

https://www.freecodecamp.org/news/rust-webassembly-serverless-tencent-cloud/

本文轉載自公眾號雲加社區(ID:QcloudCommunity)。

原文鏈接

支持多語言:Serverless雲函數如何解鎖語言限制?