宣布Cloudflare Workers支持WASI

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

640 (11).png

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

WebAssembly快速入門

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

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

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

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

我們需要更強(qiáng)的功能。

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

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

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

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

代碼細(xì)節(jié)

WASI聽(tīng)起來(lái)很不錯(cuò),但它能真正簡(jiǎn)化編程工作嗎?誰(shuí)用誰(shuí)知道。我們來(lái)看一個(gè)例子,看看它如何運(yùn)用于實(shí)踐。

首先,生成一個(gè)基本的Rust“Hello,world!”應(yīng)用程序,對(duì)其進(jìn)行編譯并運(yùn)行。

640.png

這是再簡(jiǎn)單不過(guò)的了??梢钥吹?,我們只定義了一個(gè)main()函數(shù),接著是用一個(gè)println語(yǔ)句打印到stdout。

640 (1).png

現(xiàn)在,我們針對(duì)wasm32-wasi目標(biāo)編譯這個(gè)程序,并在Wasmtime等“現(xiàn)成”的wasm運(yùn)行時(shí)中運(yùn)行。

640 (3).png

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

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

640 (2).png

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

在云中運(yùn)行CLI應(yīng)用

細(xì)心的讀者可能會(huì)注意到,我們?cè)谕ㄟ^(guò)cURL發(fā)出的HTTP請(qǐng)求中做了一點(diǎn)手腳。在這個(gè)例子中,我們實(shí)際上是分別使用HTTP請(qǐng)求和響應(yīng)主體來(lái)與Worker之間進(jìn)行stdin和stdout流傳輸。利用這個(gè)模式,可以實(shí)現(xiàn)一些非常有意思的用例,具體來(lái)說(shuō),設(shè)計(jì)為在命令行中運(yùn)行的程序可以作為“服務(wù)”部署到云中。

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

640.png

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

640 (1).png

點(diǎn)擊https://hexyl.examples.workers.dev,自己試一試。

640 (2).png

一個(gè)更有用、但也更復(fù)雜一些的例子就是將swc(swc.rs)等實(shí)用工具部署到云中并將其用作按需JavaScript/TypeScript跨平臺(tái)編譯服務(wù)。這里,我們可以執(zhí)行幾個(gè)額外步驟,確保編譯的輸出盡可能小,但除此之外,它基本上是開(kāi)箱即用的。這些步驟在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}

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

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

640 (3).png

如果我想在JavaScript Worker中使用WASI

該怎么辦?

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

640 (4).png

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

640 (5).png

回到未來(lái)

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

在此,我們非常渴望了解開(kāi)發(fā)人員對(duì)此有何看法。請(qǐng)?jiān)贒iscord或Twitter上與我們分享您所構(gòu)建的成果!

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