宣布Cloudflare Workers支持WASI

來源:Cloudflare
作者:Cloudflare
時間:2022-08-30
2399
今天,我們宣布Cloudflare Workers試驗性支持WASI(WebAssembly系統(tǒng)接口),并在wrangler2中提供支持,以便大幅提升工作便利性。我們一如既往對Primer整個WebAssembly生態(tài)系統(tǒng)充滿希望,并十分積極地采納新開發(fā)的標準。

640 (11).png

今天,我們宣布Cloudflare Workers試驗性支持WASI(WebAssembly系統(tǒng)接口),并在wrangler2中提供支持,以便大幅提升工作便利性。我們一如既往對Primer整個WebAssembly生態(tài)系統(tǒng)充滿希望,并十分積極地采納新開發(fā)的標準。

WebAssembly快速入門

那么,WASI到底是什么呢?若要了解WASI以及我們對其充滿希望的理由,就有必要快速回顧一下WebAssembly以及它周邊的生態(tài)系統(tǒng)。

借助WebAssembly,使用編譯語言編寫的代碼未來有望能夠編譯為通用二進制格式并以接近原生速度的速度在安全沙盒中運行。雖然WebAssembly是圍繞瀏覽器設計的,但模型迅速擴展到服務器端平臺,例如Cloudflare Workers(自2017年以來一直支持WebAssembly)。

WebAssembly最初設計為與Javascript一起運行,并需要開發(fā)人員直接與Javascript交互才能訪問沙盒之外的內容。換句話說,WebAssembly并沒有為I/O任務提供任何標準接口,例如與文件交互、訪問網(wǎng)絡或讀取系統(tǒng)時鐘。這意味著,如果要響應外部事件,開發(fā)人員需要負責在JavaScript中處理該事件,并直接調用從WebAssembly模塊導出的函數(shù)。類似地,如果要從WebAssembly中執(zhí)行I/O,就需要在Javascript中實現(xiàn)該邏輯并將其導入WebAssembly模塊中。

Emscripten等自定義工具鏈或wasm-bindgen等庫應運而生,用于簡化這一工作,但它們特定于語言,會帶來極大的復雜度,并且使代碼顯得十分臃腫。我們甚至構建了自己的庫workers-rs,使用wasm-bindgen以試圖讓在Rust中編寫應用程序感覺就像在Worker中原生那樣–但最后我們發(fā)現(xiàn),這不僅很難維護,而且還需要開發(fā)人員編寫特定于Workers的代碼,并且這些代碼無法移植到Workers生態(tài)系統(tǒng)之外。

我們需要更強的功能。

WebAssembly系統(tǒng)接口(WASI)

WASI旨在提供任何編譯到WebAssembly的語言都可以作為目標的標準接口。點擊此處閱讀Lin Clark的原創(chuàng)文章,其中很漂亮地做了介紹–甚至還做了代碼卡通。簡而言之,Lin將WebAssembly形容為適合“概念機器”的匯編語言,而WASI則是適合“概念操作系統(tǒng)”的系統(tǒng)接口。

這種系統(tǒng)接口標準化為現(xiàn)有工具鏈針對wasm32-wasi目標交叉編譯現(xiàn)有代碼庫鋪平了道路。通過wasi-sdk和Rust工具鏈已經(jīng)實現(xiàn)了極大進展,尤其是在Clang/LLVM中。這些工具鏈利用某個版本的Libc,它提供POSIX標準API調用,這些調用是在WASI“系統(tǒng)調用”基礎上構建的。甚至在TinyGo和SwiftWasm這樣更為邊緣化的工具鏈中也有基本實現(xiàn)。

實際說來,這意味著現(xiàn)在可以編寫的應用程序不僅能夠與實現(xiàn)該標準的任何WebAssembly運行時互操作,還能與任何符合POSIX標準的系統(tǒng)互操作!這意味著,完全相同的“Hello World!”可在本地Linux/Mac/Windows WSL機器上運行。

代碼細節(jié)

WASI聽起來很不錯,但它能真正簡化編程工作嗎?誰用誰知道。我們來看一個例子,看看它如何運用于實踐。

首先,生成一個基本的Rust“Hello,world!”應用程序,對其進行編譯并運行。

640.png

這是再簡單不過的了。可以看到,我們只定義了一個main()函數(shù),接著是用一個println語句打印到stdout。

640 (1).png

現(xiàn)在,我們針對wasm32-wasi目標編譯這個程序,并在Wasmtime等“現(xiàn)成”的wasm運行時中運行。

640 (3).png

太棒了!相同的代碼在多個POSIX環(huán)境中順利編譯并運行。

最后,來看看我們剛才為Wasmtime生成的二進制文件,但這次改用Wrangler2將其發(fā)布到Workers。

640 (2).png

不出所料,成功了!相同的代碼兼容了多個POSIX環(huán)境,并且相同的二進制文件兼容了多個WASM運行時。

在云中運行CLI應用

細心的讀者可能會注意到,我們在通過cURL發(fā)出的HTTP請求中做了一點手腳。在這個例子中,我們實際上是分別使用HTTP請求和響應主體來與Worker之間進行stdin和stdout流傳輸。利用這個模式,可以實現(xiàn)一些非常有意思的用例,具體來說,設計為在命令行中運行的程序可以作為“服務”部署到云中。

“Hexyl”就是一個完全開箱即用的例子。這里,我們對本地機器上的二進制文件執(zhí)行“cat”命令,并通過“pipe”命令將輸出輸送到curl,后者會通過POST命令將輸出發(fā)布到我們的服務,并流傳輸回結果。按照我們用于編譯“Hello World!”的步驟,我們可以編譯hexyl。

640.png

無需任何修改,我們就能利用一個現(xiàn)實的程序來創(chuàng)建立即就能運行或部署的用例。同樣,我們讓wrangler2預覽hexyl,但這次給它提供一些輸入。

640 (1).png

點擊https://hexyl.examples.workers.dev,自己試一試。

640 (2).png

一個更有用、但也更復雜一些的例子就是將swc(swc.rs)等實用工具部署到云中并將其用作按需JavaScript/TypeScript跨平臺編譯服務。這里,我們可以執(zhí)行幾個額外步驟,確保編譯的輸出盡可能小,但除此之外,它基本上是開箱即用的。這些步驟在https://github.com/zebp/wasi-example-swc中詳述,但目前我們只是粗略概括一下,看看托管示例。

$ echo "const x = (x, y) => x * y;" | curl -X POST --data-binary @- https://swc-wasi.examples.workers.dev/ --output -var x=function(a,b){return a*b}

最后,我們還可以對C/C++執(zhí)行相同的操作,但需要做一些修改,將Makefile調整正確。這里有一個例子,說明如何編譯zstd并將其上傳作為流傳輸壓縮服務。

https://github.com/zebp/wasi-example-zstd

640 (3).png

如果我想在JavaScript Worker中使用WASI

該怎么辦?

利用Wrangler,可以非常輕松地部署代碼,不用管Workers生態(tài)系統(tǒng),但在一些情況下,可能實際上需要從Javascript調用基于WASI的WASM模塊。這可以使用以下簡單樣板來實現(xiàn)。https://github.com/cloudflare/workers-wasi中將保留一份更新的README。

640 (4).png

現(xiàn)在借助JavaScript樣板和wasm,我們可以利用Wrangler的WASM功能輕松部署Worker。

640 (5).png

回到未來

過去幾十年積極關注編程發(fā)展的讀者可能會注意到,這非常類似于RFC3875,也就是我們常說的CGI(公共網(wǎng)關接口)。雖然我們這個例子顯然不符合該規(guī)范,但不難想象,完全可以加以擴展,將基本“命令行”應用程序的stdin轉變?yōu)橥耆墒斓膆ttp處理程序。

在此,我們非常渴望了解開發(fā)人員對此有何看法。請在Discord或Twitter上與我們分享您所構建的成果!

立即登錄,閱讀全文
原文鏈接:點擊前往 >
文章來源:Cloudflare
版權說明:本文內容來自于Cloudflare,本站不擁有所有權,不承擔相關法律責任。文章內容系作者個人觀點,不代表快出海對觀點贊同或支持。如有侵權,請聯(lián)系管理員(zzx@kchuhai.com)刪除!
優(yōu)質服務商推薦
更多
掃碼登錄
打開掃一掃, 關注公眾號后即可登錄/注冊
加載中
二維碼已失效 請重試
刷新
賬號登錄/注冊
個人VIP
小程序
快出海小程序
公眾號
快出海公眾號
商務合作
商務合作
投稿采訪
投稿采訪
出海管家
出海管家