😓

LLRTはカスタムランタイムLambdaで動かすと動くけど、Web標準APIは動かない

2024/02/09に公開

★2024/6 追記
2024/02/09時点の情報です。ある程度解決している部分もあるため、実際はこの時より動きます。

LLRT

https://github.com/awslabs/llrt

AWSが突然公開したLLRT (Low Latency Runtime)。

Rust+QuickJSな新しいJSランタイムで、「AWS Lambdaで実行される他の JavaScript ランタイムと比較して、最大10 倍以上の高速な起動と最大2 倍の全体的なコストの削減を実現します。」(Google翻訳)とのこと。目指すところは面白い。

互換性はこんな感じらしい。

Please note: Even though LLRT supports ES2020 it's is NOT a drop in replacement for Node.js. Consult Compatibility matrix and API for more details. All dependencies should be bundled for a browser platform and mark included @aws-sdk packages as external.

早速動かしてみる。

Build

https://github.com/awslabs/llrt?tab=readme-ov-file#building-from-source

を参考に Amazonlinux 2023環境(x86.64)で作業していく。

ここで--recursiveをサボって外すと後々zstd/が見つからずにハマるから気を付ける。

# Clone code and cd to directory
git clone https://github.com/awslabs/llrt.git --recursive
cd llrt

Rust入れるところは手順通り

# Install rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | bash -s -- -y
source "$HOME/.cargo/env"

cmakeが足りなかったので足した。Zigは正規の導入方法がうまくいかなかったので回答してPATHを通している。

sudo dnf update -y
sudo dnf -y install make zstd cmake

# Install Zig
curl https://ziglang.org/builds/zig-linux-x86_64-0.12.0-dev.2665+919a3bae1.tar.xz -O
tar -xvf zig-linux-x86_64-0.12.0-dev.2665+919a3bae1.tar.xz
echo 'export PATH=$PATH:/workspaces/sample/zig-linux-x86_64-0.12.0-dev.2665+919a3bae1' >> ~/.bashrc
source ~/.bashrc

後は手順通り。

# Install Node.js packages
corepack enable
yarn

# Install generate libs and setup rust targets & toolchains
make stdlib && make libs

# Build release for Lambda
make release-x64

これでllrt/target/x86_64-unknown-linux-musl/release/bootstrapにビルドできることがわかる。

ちなみに公式のコマンドだとmake release-x86となっているが、そんなものはないので無駄にはハマった。

※修正依頼済

https://github.com/awslabs/llrt/pull/113

Deploy

今回はHonoのサンプルアプリをデプロイしていく。

npx create-hono@latestでaws-lambda用のプロジェクトを立ち上げる。

ビルド設定は

https://github.com/awslabs/llrt?tab=readme-ov-file#using-node_modules-dependencies-with-llrt

package.jsonはこう変えて、CustomRuntimeなLambdaにデプロイしてみる。

package.json
-    "build": "esbuild --bundle --outfile=./dist/index.js --platform=node --target=node18 ./src/index.ts",
+    "build": "esbuild --bundle --outfile=./dist/index.js --platform=node --target=es2020 --format=esm --bundle --external:@aws-sdk --external:uuid ./src/index.ts",
-    "zip": "zip -j lambda.zip dist/index.js",
+    "zip": "zip -j lambda.zip dist/index.js dist/bootstrap",

結果

それではいよいよ動かしてみる!

うん……なるほどね…………
メッセージから想定するに、Honoのコア部分が利用しているResponseに対応していない様子。

https://developer.mozilla.org/ja/docs/Web/API/Response/Response

WinterCGの仕様はロードマップに入っているので、この辺りが対応できると嬉しいな。

https://github.com/awslabs/llrt/issues/112

ちなみにLambdaのサンプルコード程度なら動きます。性能は確認できていませんが……

おまけ

ちょうど私がこれを確認したあたりで公開された「AWS CDK LLRT Function construct」を使うと、もっとスムーズに試せそう。

https://github.com/tmokmss/cdk-lambda-llrt

というかビルド要らなかったんかw

https://github.com/awslabs/llrt/releases

まとめ

ということでHono × LLRT一番乗りできるかな、と思ったら想定外のところでハマってしまいました。まだBata版なので今後に期待です。制約の多いCloudFront FunctionsのRuntimeを置き換えてくれると嬉しい!

私の屍を越えてパフォーマンス検証してくれる方がいたら嬉しいなあ。。。

Discussion