Serverless的未來WASM

1 什么是WASM

WASM是WebAssembly的縮寫,WebAssembly是一種用于基于堆棧虛擬機的二進制指令格式。Wasm 被設計為編程語言的可移植編譯目標,支持在Web上為客戶端和服務器應用程序服務部署∩龋總結起來WASM是一種可以在現(xiàn)代Web瀏覽器種運行的新型代碼耐朴,是一種類似低級匯編的語言,擁有緊湊的二進制格式盹憎,能夠以接近本機的性能運行筛峭。為高級語言(C/C++、Go陪每、Rust影晓、Python等)提供編譯目標,通過這種方式Rust編寫的程序就可以在Web中運行檩禾。WASM和JS可以一起配合工作挂签。

2 WASM的特點

2.1 高效快速

WASM非常的輕量且加載速度極快。WASM的目標是以原生的速度運行盼产,從而充分利用各種平臺都擁有的通用硬件能力饵婆。使用最常見、最普通的硬件提升軟件運行的效率辆飘。

2.2 安全

WebAssembly 描述了一個內存安全的沙箱執(zhí)行環(huán)境啦辐,甚至可以在現(xiàn)有的 JavaScript 虛擬機中實現(xiàn)谓传。當嵌入到 Web 中時蜈项,WebAssembly 將強制執(zhí)行瀏覽器的同源和權限安全策略。

2.3 開放可調試

WebAssembly 旨在以文本格式漂亮地打印調試信息续挟,用于調試紧卒、測試、實驗诗祸、優(yōu)化跑芳、學習、教學和手工編寫程序(這個有點酷)直颅。在網絡上查看 Wasm 模塊的源時將使用文本格式(這簡直是調試的魔法糖)博个。

2.4 開放Web平臺的一部分

WebAssembly 旨在保持 Web 的無版本、功能測試和向后兼容的特性功偿。WebAssembly 模塊能夠在JavaScript上下文內外調用盆佣,可以訪問瀏覽器的函數(shù)。WebAssembly也支持在非瀏覽器環(huán)境運行械荷。

3 WSAI

WASM如此的優(yōu)秀共耍,偉大的程序員當然不想WASM只能在Web中得到應用,WASM應該在任何系統(tǒng)吨瞎、設備上得到應用痹兜,為此設計了WASM的模塊化系統(tǒng)接口WASI,通過標準的接口和主機環(huán)境進行交互颤诀。

4 運行時

WASM的執(zhí)行依賴運行時環(huán)境字旭,目前字節(jié)聯(lián)盟開發(fā)了單機的輕量化運行時wasmtime对湃。wasmtime非常的輕巧,Windows下大小只有2MB左右谐算。

wasmtime的主要特點包括:

輕量:WASM的單機運行時熟尉,可按需擴展。微信芯片和大型服務器都是無縫使用洲脂〗锒可內嵌到大多數(shù)的應用程序。因為輕量可以無處不在恐锦。

:建立在優(yōu)化的 Cranelift 代碼生成器之上往果,可以在運行時快速生成高質量的機器代碼。

可配置:無論您需要提前預編譯您的 wasm 還是在運行時解釋它一铅,Wasmtime 都能滿足您執(zhí)行 wasm 的所有需求陕贮。

WASI支持:支持豐富的API集合,通過WASI標準和主機環(huán)境交互潘飘。

標準:Wasmtime 通過了官方的 WebAssembly 測試肮之,實現(xiàn)了 wasm 的官方 C API,也實現(xiàn)了未來對 WebAssembly 的提案卜录。 Wasmtime 開發(fā)人員也一直密切參與 WebAssembly 標準流程戈擒。

5 快速體驗

5.1 使用Rust編寫WASM

可以使用rust工具將rust源碼編譯為wasm,所以我們可以用Rust語言編寫程序艰毒,然后編譯成wasm格式筐高,然后使用wasmtime運行wasm或者在其他語言比如Go中運行wasm,這聽起來是不是很酷,下面以一個簡單的程序進行說明丑瞧。

第一步:將WebAssembly設置為cargo編譯的目標對象

rustup target add wasm32-wasi

第二步:創(chuàng)建一個簡單的Rust項目

cargo new hello-wasm

將main.rs函數(shù)修改為如下:

fn main() {
    println!("Hello, WASM")
}

第三步:將Rust代碼編譯成WASM

cargo build --target wasm32-wasi

在hello-wasm/target/wasm32-wasi/debug目錄下可以找到編譯后的文件hello-wasm.wasm

5.2 使用wasmtime運行wasm

在hello-wasm.wasm所在的目錄打開命令行柑土,執(zhí)行下面的命令運行wasm:

wasmtime hello-wasm.wasm

屏幕上將會正確打印:Hello, WASM

檢查wasmtime是否正確安裝

下面我們按照WASM的規(guī)范編寫一個計算最大公約數(shù)gcd的函數(shù)绊汹,然后使用多種熟悉的編程語言去調用gcd函數(shù)稽屏。

gcd.wat的內容如下:

(module
  (func $gcd (param i32 i32) (result i32)
    (local i32)
    block  ;; label = @1
      block  ;; label = @2
        local.get 0
        br_if 0 (;@2;)
        local.get 1
        local.set 2
        br 1 (;@1;)
      end
      loop  ;; label = @2
        local.get 1
        local.get 0
        local.tee 2
        i32.rem_u
        local.set 0
        local.get 2
        local.set 1
        local.get 0
        br_if 0 (;@2;)
      end
    end
    local.get 2
  )
  (export "gcd" (func $gcd))
)

5.3 使用Rust運行gcd函數(shù)

第一步:創(chuàng)建gcd項目

cargo new gcd

第二步:添加依賴

[dependencies]
wasmtime = "0.31.0"
anyhow = "1.0.45"

第三步:編寫main.rs代碼運行gcd函數(shù)

use anyhow::Result;
use wasmtime::*;

fn main() -> Result<()> {
    let mut store = Store::<()>::default();
    let module = Module::from_file(store.engine(), "gcd.wat")?;
    let instance = Instance::new(&mut store, &module, &[])?;

    let gcd = instance.get_typed_func::<(i32, i32), i32, _>(&mut store, "gcd")?;

    println!("gcd(6, 27) = {}", gcd.call(&mut store, (6, 27))?);
    Ok(())
}

第四步:運行程序查看輸出結果

cargo run

程序將會輸出:

gcd(6, 27) = 3

5.4 使用Bash運行wasm

第一步:編寫gcd.sh運行gcd函數(shù)

#!/bin/bash

function gcd() {
  # Cast to number; default = 0
  local x=$(($1))
  local y=$(($2))
  # Invoke GCD from module; suppress stderr
  local result=$(wasmtime gcd.wat --invoke gcd $x $y 2>/dev/null)
  echo "$result"
}

# main
for num in "27 6" "6 27" "42 12"; do
  set -- $num
  echo "gcd($1, $2) = $(gcd "$1" "$2")"
done

第二步:運行gcd.sh

sh gcd.sh

程序將會輸出:

gcd(27, 6) = 3
gcd(6, 27) = 3
gcd(42, 12) = 6

5.5 使用Python運行gcd

第一步:安裝wasmtime

pip install wasmtime

第二步:編寫gcd.py代碼運行gcd函數(shù)

from wasmtime import Store, Module, Instance

store = Store()
module = Module.from_file(store.engine, 'gcd.wat')
instance = Instance(store, module, [])
gcd = instance.exports(store)["gcd"]

print("gcd(6, 27) = %d" % gcd(store, 6, 27))

第三步:運行gcd.py

python gcd.py

程序將會輸出:

gcd(6, 27) = 3
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市西乖,隨后出現(xiàn)的幾起案子狐榔,更是在濱河造成了極大的恐慌,老刑警劉巖浴栽,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荒叼,死亡現(xiàn)場離奇詭異,居然都是意外死亡典鸡,警方通過查閱死者的電腦和手機被廓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來萝玷,“玉大人嫁乘,你說我怎么就攤上這事昆婿。” “怎么了蜓斧?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵仓蛆,是天一觀的道長。 經常有香客問我挎春,道長看疙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任直奋,我火速辦了婚禮能庆,結果婚禮上,老公的妹妹穿的比我還像新娘脚线。我一直安慰自己搁胆,他們只是感情好,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布邮绿。 她就那樣靜靜地躺著渠旁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪船逮。 梳的紋絲不亂的頭發(fā)上顾腊,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機與錄音傻唾,去河邊找鬼投慈。 笑死承耿,一個胖子當著我的面吹牛冠骄,可吹牛的內容都是我干的。 我是一名探鬼主播加袋,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼凛辣,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了职烧?” 一聲冷哼從身側響起扁誓,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蚀之,沒想到半個月后蝗敢,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡足删,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年寿谴,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片失受。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡讶泰,死狀恐怖咏瑟,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情痪署,我是刑警寧澤码泞,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站狼犯,受9級特大地震影響余寥,放射性物質發(fā)生泄漏。R本人自食惡果不足惜悯森,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一劈狐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧呐馆,春花似錦肥缔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至收班,卻和暖如春坟岔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背摔桦。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工社付, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人邻耕。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓鸥咖,卻偏偏與公主長得像,于是被迫代替她去往敵國和親兄世。 傳聞我的和親對象是個殘疾皇子啼辣,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內容