支持多語言: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 函數的內部處理流程如下所示:

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

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

SCF_RUNTIME_API:SCF_RUNTIME_API_PORT

HTTP API 定義如下圖所示:

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 模板示例做說明,如下圖所示,程序包裏有:

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

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

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

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

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

以上就是一個 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雲函數如何解鎖語言限制?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章