阿裡雲函數計算目前支援C#、Java、Python、Go等大部分語言,對于一些定時任務是非常适合的。最近有一些工程使用Rust重寫了也想部署到阿裡雲函數計算上,這裡來看可以使用Custom Runtime/Container。
Custom Runtime/Container模式
這個模式本質上是自定義腳本啟動一個http服務,然後Serverless平台轉發請求到你的http服務,這個請求header中有一些特殊資訊,極端的将不考慮啟動速度和性能等等,其實是可以無障礙遷移大部分服務的(存儲和資料庫可能需要改造)。
這個運作環境預設包含了Python3,Java 8等常見依賴,對于Rust這種編譯成二進制檔案的就更簡單了。最終産物是一個zip包,包含啟動檔案bootstrap和其他依賴即可。
Custom Container模式可以了解成增強模式,如果Custom Runtime不可用,一般是由于特殊的本地依賴導緻,Custom Container模式的産出是一個鏡像,不過由于鏡像的大小比代碼包大,是以計費上要多一些,包含拉取鏡像的費用。是以這兩者需要根據情況來決策,盡可能使用Runtime模式。這樣費用和速度上都好一些。
代碼改造
這裡使用的是funcraft工具專門用于部署,template.yml檔案包含描述資訊,代碼放在code目錄。
在Cargo.toml中新增兩個依賴
tokio = { version = "1.12.0", features = ["full"] }
warp = "0.3.0"
修改main.rs用warp啟動一個http服務
async fn main() {}pretty_env_logger::init(); // POST /invoke let route = warp::path!("invoke") .and(warp::post()) .and_then(handler::run); info!("Starting server ..."); warp::serve(route).run(([0, 0, 0, 0], 9000)).await;
其中handler:run就是原來代碼入口,簽名如下
pub async fn run() -> Result {
為了友善自動部署,代碼建構用了Docker (FROM rust:1),加一個Makefile如下
build-img:build: build-imgdocker build -t fc-rust-runtime -f build-image/Dockerfile build-image
deploy: builddocker run --rm -v $$(pwd):/tmp fc-rust-runtime bash -c "cd /tmp/code/ && cargo build --release && mv target/release/code bootstrap && chmod +x bootstrap && rm -rf target/"
fun deploy -y
這樣直接執行make deploy即可。
優化代碼包大小
因為代碼包是需要拉取的,特别是冷啟動時間,是以盡可能降低大小是有必要的。
首先是看下除了bootstrap以外其他檔案是否可以删除,比如源檔案(*.rs)就不需要,一般來說必要的檔案常見的有log4rs.yml還有migration檔案夾等,也可能隻需要一個bootstrap就行了。
其次就是優化生成物本身的大小,cargo build –release本身包含了一些優化,但是為了更小的體積一般還會配置這些
[profile.release]
opt-level = "z"
lto = true
codegen-units = 1
最後就是strip,目前nightly可以直接使用,但是stable還是需要手動執行下,也可以使用cargo-strip。nightly配置如下
cargo-features = ["strip"]
strip = "symbols"
參考
除了Rust以外,我還有一些Golang的函數,從體驗上看部署流暢度和記憶體消耗Rust有一定優勢,但是也不算很大,因為目前的計費方式上,記憶體最小是128M,相同功能的Golang函數平均比Rust多10M到20M,對于實際費用影響不大,定時任務對于時間敏感度也沒有那麼高。
參考文檔:
https://help.aliyun.com/document_detail/132044.html https://help.aliyun.com/document_detail/179367.html https://github.com/htynkn/faas-collections/tree/master/update-forked-repo-rust