開発ブログ

株式会社Nextatのスタッフがお送りする技術コラムメインのブログ。

電話でのお問合わせ 075-744-6842 ([月]-[金] 10:00〜17:00)

  1. top >
  2. 開発ブログ >
  3. Wasmer >
  4. Onyx言語でHTTPサーバーを実装し、Wasmer Edgeにデプロイする

Onyx言語でHTTPサーバーを実装し、Wasmer Edgeにデプロイする

こんにちは、ナカエです。 先週末は少し暖かかったかと思えばまた寒くなりましたね。

本日の記事はWasmer Edgeというエッジにアプリケーションをデプロイできるサービスと新しいプログラミング言語である Onyx を合わせて試したという内容です。

まずはそれぞれの簡単な紹介から入ります。

Wasmer Edgeとは

Wasmer Edge はエッジロケーションにWebAssemblyのランタイムを展開し、Wasmバイナリをアプリケーションとして安価にスケーラブルに動かせると謳うサービスです。米Wasmer社が提供しています。

個人的にはブラウザ側だけでなくサーバー側であるエッジでまでJavaScript/TypeScriptという選択肢だけになるのはちょっと……という気持ちがあり、エッジでのWasmの実行についても興味を寄せています。

ユーザーに近いロケーションでコンテナを動かす、ということであれば Fly.io などでもやっていることですが、Wasmランタイムがコンテナランタイムの代替手段となりえるならセキュリティ面やパフォーマンス面で有利です。利用側もアプリの実装以外で考えることが減るのではないかと期待しています。

Docker DesktopにWebAssemblyランタイムが統合される などの動きもあり、今後エコシステムの整備は加速していきそうです。

Wasmer Edge はまだBetaではありますが10/6にGAとなっており、Tokyoリージョンも追加されています。

onyx-wasmer-edge-edge-comparison.png

競合との比較にてコールドスタートが 50ナノ秒と表記されていたり、HTTP接続だけではなくTCP接続も扱えるとメリットをアピールしており、自信のほどが窺えます。

言語サポートには Rust, JS, C, Python, Ruby とあり、現時点でも一般的なエッジコンピューティングのサービスより対応幅が広いです。Wasmを生成できるなら言語はなんでもいい、という感じになってくれれば素晴らしいですね。

プログラミング言語 Onyx とは

onyx-wasmer-onyx-site.png
 

Wasmer社がブログで紹介したことで話題になった Onyx はWebAssemblyへのコンパイルに特化した言語で、開発者は Brendan Hansen 氏です。

Wasm特化というだけあってWebAssemblyへのコンパイルが非常に高速とのこと。

また、Onyxの構文は、Go、Jai、Odinといった他の命令型プログラミング言語にインスパイアされているそうですが、パイプ演算子など関数型プログラミングのスタイルに合う言語機能も用意されています。

さて、ここからはOnyxとWasmer Edgeを試してみましょう。

環境

  • macOS Monterey
  • Intel Core i5
  • Wasmer CLI 4.2.4
  • Onyx v0.1.8
  • zsh 5.8.1

今回はWasmerへのアカウント登録手順は割愛し、すでにアカウントを保持しているものとします。

Onyxのインストール

Onyxの公式サイト の説明に従い、下記のワンライナーを実行します。

sh <(curl https://get.onyxlang.io -sSfL)

インストール後はターミナルを新規に開き、 onyx version コマンドにて、バージョンとランタイムを確認できます。

$ onyx version

Onyx toolchain version v0.1.8
Built on Wed Nov 29 01:49:11 2023
Runtime: wasmer

Onyxのパッケージの作成

以下はドキュメントの HTTP Server in Onyx を参考に進めます。

まずはディレクトリを作ってOnyxのパッケージを作成し、

mkdir my-http-server
cd my-http-server
onyx package init

今回利用する http-server のパッケージを依存として追加します。

onyx package add http-server
onyx package sync

パッケージの設定は onyx-pkg.kdl というファイルに保存されているようですね。

$ cat onyx-pkg.kdl

package {
    name "my-http-server" 
    author "n1215" 
    url "" 
    description "My first HTTP Server project" 
    version "0.0.1" 
}

config {
    dependency_source_path "./lib" 
    dependency_binary_path "./bin" 
}

dependencies {
    http-server "0.2.24" git="http://github.com/onyx-lang/pkg-http-server" 
}

HTTPサーバーの実装

サーバーが返すHTMLを少し変更していますが、おおむねドキュメントの通りです。

#load "./lib/packages"

use core {*}

use http
use http.server { Request, Response, route }

#tag route.{ .GET, "/" }
index :: (req: &Request, res: &Response) {
    res->html("<h1>Http Server in Onyx!</h1>");
    res->status(200);
    res->end();
}

main :: () {
    router := http.server.router();
    router->collect_routes();
    http.server.cgi(&router);
}

Wasmerにデプロイする前提で、http.server.tcpではなく、http.server.cgi を利用しているところがポイントです。

Wasmバイナリを生成

コードをコンパイルして、WASIランタイム向けのWasmを生成します。

onyx build main.onyx -r wasi -o my-http-server.wasm

ちなみに生成したWasmのファイルサイズは250KBでした。

さて、記事の後半ではこのWasmをWasmerにデプロイしていきます。

WasmerのCLIをインストール

Wasmerにデプロイするアプリケーションの操作は公式のCLIを通じて行います。

Install Wasmer に従って

curl https://get.wasmer.io -sSfL | sh

を実行するだけでOKです。

wasmer --version コマンドにて、Wasmerがインストールされていることを確認できます。

$ wasmer --version

wasmer 4.2.4

Wasmer アプリケーションの作成

wasmer.tomlの作成

デプロイの前にWasmer側にアプリケーションを作成する必要があります。

下記の内容でwasmer.tomlファイルを作成します。 <your-namespace><your-package-name> は適宜置き換えてください。

[package]
name = "<your-namespace>/<your-package-name>"
version = "0.1.0"
description = "My first HTTP server"
license = "MIT"
 
[[module]]
name = "server"
source = "my-http-server.wasm"
abi = "wasi"
 
[[command]]
name = "server"
module = "server"
runner = "https://webc.org/runner/wcgi"
 
[command.annotations.wasi]
env = ["SCRIPT_NAME=rust_wcgi"]
 
[command.annotations.wcgi]
dialect = "rfc-3875"

次に

wasmer login

で登録したアカウントでログインし、

wasmer app create

のコマンドを実行してHTTP serverを選択します

$ wasmer app create

App type:
  Static website
> HTTP server
  Browser shell
  JS Worker (experimental)
  Python Application

ほかにも設定がありますが、wasmer.tomlに設定されている内容が利用されるので基本的にはデフォルトを選択で大丈夫です。

wasmer deploy コマンドを試したいので、最後の質問の「Would you like to publish the app now?」のみnoを選択しておきます。

$ wasmer app create

App type: HTTP server
Who should own this package?: n1215
Found local package: 'n1215/my-http-server@0.1.0'
Use package 'n1215/my-http-server' yes
What should be the name of the app? <NAME>.wasmer.app: n1215-my-http-server
Would you like to publish the app now? no
Writing app config to '/Users/ken/Workspace/my-http-server/app.yaml'
To (re)deploy your app, run 'wasmer deploy'

この時点でapp.yamlが生成されているのが確認できます

---
kind: wasmer.io/App.v0
name: n1215-my-http-server
package: n1215/my-http-server
debug: false

Wasmer へのデプロイ

デプロイは下記コマンドを実行するだけです。

wasmer deploy

アプリの公開URLは wasmer app createコマンドで指定したものとなっています。 バージョンごとにも https://{英数}.id.wasmer.app のようなURLが発行されるようです。

アクセスすると、HTTPサーバーの動作が確認できます。

onyx-wasmer-edge-deployed.png

まとめ

WebAssemblyに特化したプログラミング言語Onyxを利用してWasmバイナリを作成してWasmerにデプロイし、動作を確認できました。

Onyx言語はツールチェインを含めなかなか使いやすそうです。 WasmerはHerokuやFly.ioのようにCLIだけでサクッとデプロイできるのも手軽で良いですね。 エッジでのWasmの実行については、今後も動向を注視していこうと思います。

TOPに戻る