てけノート

on the foot of giants

[ngx_mruby]使ってみた結果、nginx.confが400行超から70行に

   


ngx_mrubyとは?

nginxの設定の内部で、mrubyを使うことができる拡張。
nginxとluaの方が使用例が豊富だが、mrubyだとrubyとほぼ互換性がある形で利用できるため、学習コストが低い。
基本的にはmrubyの方が高速らしいが、ノンブロッキング処理できないよね、というところでluaの方が強い部分もある。
詳しい比較はこちら

使ってみた結果

nginxのconfって普通に設定書くとやたら長くなってしまうと思うんですよ。if文の入れ子がNGだったりとか、そもそもif文自体イケてないよね、という話とか by 公式

弾きたいIPを配列で取り扱えたらな〜とか、
外部のyamlに設定ファイル書き出したいなーとか(通常のnginxでできるかどうかはよく知りませんが)
そしたらclassも使いたいな〜とか
そういう希望があったので、mrubyを使ってみました。

結果、タイトルにある通り、かなりいい感じに実装できている感じがします。

problem-solution

mgemを足すのが大変

rubyだとgem installとかで好きなときに追加できると思うんですが、mrubyの場合ビルドし直しになってしまうんですよね。
インストールについて

解決策としては、Dockerの利用でした。公式が用意してくれているので、これをforkして使っています。
forkすれば、設定ファイルを書き換えてdocker buildするだけなので、簡単です。

使える関数が違ったり、rubyとの違いがけっこうある

最初は、使える関数やクラスが不明だったので、mrubyの公式、coreモジュールを見てたんですが、
試したら以外と使える関数が多かったりしたので、これはローカルでとりあえずrubyでやるっぽく書いてテストしてみた方が良さそうです。
見るべき公式が違うのかな…

書いててハマったのが、やはりrubyを期待して書くと動作しないところ。例えば
・Arrayクラスにfindやappendがないので、bsearchやinsertで対応
・Hashクラスにkeysがない
みたいな部分です。もしかしたら確認しきれてないだけで、書いたら動作するのかも。
この記事が詳しい。

gemのバージョン問題

例えば、他の.rbファイルを読み込むという非常に重要なmruby-requireとか、公式に登録されているgemはv1.17系だとビルドできますが、
v1.18系だとビルド失敗しました。
ので、なぜかある二つ目のmruby-requireを使ってます。こちらの方がメンテナンスもされてるっぽい。

情報リソースの少なさ

ググりエンジニアとしては、ググってヒットしないのはなかなか大変です。
よかった記事たち:
100行あったmod_rewirteを ngx_mrubyで書き換えた話
ISUCON4予選問題をngx_mrubyだけで解いてみた(ノウハウ編)
mruby + ngx_mrubyでアプリケーションを実装するという選択肢

すぐ 次の検索結果を表示しています: nginx ruby とか言われて草。

まとめ

試行錯誤の結果、目的が果たせたので大変満足です。selectやmapが使えるのは大変ありがたい。
使いこなすにはいたってないので、今後要チューニング。

 - インフラ, プログラミング