update.今年の秋頃に将来nginxでJavaScriptが書けるようになるという話が出ましたが、nginxには元々サードパーティモジュールの中でも有名なngx_luaがあります。Calendarを見るにngx_mrubyも盛り上がってきているようです。そこで両者の比較エントリを書いてみようと思います。ngx_luaまずngx_mrubyについてはこのカレンダーでさんざん語られてるのでngx_luaについて。ngx_luaは簡単に言うとngx_mrubyと同じようなこと(あるいはそれ以上のこと)がLuaでできるnginxのサードパーティモジュールです。World!」はこんな感じで書けます。";}ngx_luaで利用できるLua処理系ngx_luaではLua5.1とLua5.1互換のLuaJITが利用できます。逆に言うとLua5.2以上だとビルドできないので注意しましょう。ngx_luaでLuaJITを利用したい場合はOpenRestyが簡単でオススメです。書いていてngx_mrubyの方が高速です(ところでstaticファイルの配信との比較もありますが、文字列返すだけのベンチマークと比較するのはあまり意味がない気がします)。このベンチマークにはLuaJITとの比較がないので試しに手元で計ってみましたが、それでもngx_mrubyの方が高速でした。mrubyとLuaJITではLuaJITの方が圧倒的に速いので、両者の速度の違いはモジュールの実装に起因するものと考えられます。(ngx_luaはハンドラ内で毎回コルーチンを起動するので多分そのオーバーヘッドが大きい)ngx_mrubyとngx_luaでかけられるフック両者ともにnginxのいろいろな実行フェーズにフックをかけれますが、かけられる数だけならngx_mrubyの方が多いです。Directives利用可能な正規表現エンジンngx_mrubyとngx_luaとでは利用できる正規表現エンジンに違いがあります。mruby-regexp-pcre)は利用できません。ngx_luaはLua標準の正規表現とPCREが利用できます。ちなみにngx_mrubyでPCREベースの正規表現を利用できない理由はこちら。データ共有の仕組みngx_luaにはngx.shared.DICTのようにデータを共有メモリに保存してワーカープロセス間で共有したり、ngx.ctxのようにリクエストの処理コンテキスト毎にデータを受け渡すしくみがあります。ngx_mrubyにはまだないようです。ngx_luaにあってngx_mrubyにないものさてここまで説明した感じだとngx_mrubyとngx_luaにはあまり差がない、あるいは高速な分ngx_mrubyの方が良いと思うかもしれません。実際一般的にはLuaよりmrubyの方が書きやすいという人もいるでしょうし、より高速というだけでも十分対抗できると思います。現在は基本的な機能の扱いについてはほとんど差がないと言ってもいいでしょう。(足らなかったらmrbgems足せば大体事足りるし)ただ、昔ngx_luaとGoでRTB広告を配信してた時期にngx_mrubyに足りないと思っていたものが一つあります。それがノンブロッキング処理のサポートです。通常nginxのようなイベント駆動型のWebサーバはそのアーキテクチャの特性上prefork型のWebサーバと比べて非常に少ないワーカー数で稼働させますが、プログラムがブロッキングするケースが増えてくるとワーカーの数を増やさなければならず段々prefork型のサーバに近づいていってしまい、パフォーマンスが悪くなる問題があります。ノンブロッキング処理は非常に重要です。(worker_processesが200のnginxとか見たことある?)ngx_luaだとngx.location.captureやngx.socket.tcpなんかがそれにあたります。ngx.location.capturengx.location.captureの説明はこのへんがわかりやすいですが、簡単に言うとnginxのサブリクエストをノンブロッキングに処理できます。言うとプログラム自体はブロッキング処理的に記述できるというのがミソです。前職の広告配信の例で言うと外部の広告サーバにngx_luaからリクエストを飛ばす際に重宝していた機能です。';}ngx.socket.tcpngx.socket.tcpはnginxのノンブロッキングTCPソケットをLuaでラップしたものです。memcachedやMySQL、Redisなんかにつなぎに行くドライバ↓がありますが、これらはすべてngx.socket.tcpを使って書かれています。lua-resty-memcachedlua-resty-mysqllua-resty-redisngx_mrubyでノンブロッキング処理をサポートするにはこれは主に開発者視点の話ですが、ngx_mrubyでノンブロッキング処理をサポートするにはnginxのイベント駆動エンジンにべったりと乗っかる必要があります。mruby-uvは使えません。mrubyのステートマシン上ではなくnginx上のイベントエンジンで処理する必要があるためです。これを実装するにはコルーチンが必須で、mrubyだとmruby-fiberを使う感じになるのかなと思います。LuaはCからコルーチンを直接操作できる(Matz曰く「心臓が見えている」)のに対して、mrubyの場合fiberがmrbgemsになっててCから直接触るのが難しいのでそのあたりを解決する必要がありそうです。ReliabilityFollowMercariフリマアプリ「メルカリ」を、グローバルで開発しています。upLoginユーザーは見つかりませんでした。