ngx_mruby v2 の新機能を見る


@matsumotory さんが ngx_mrubyv2-dev を開発中ということで、社のプロダクションに入れていくため新機能について調べたのでまとめる。

機能としては、大きく以下のような追加になるとのこと。

  • return の実装
  • Nginx::Async.sleep の実装
  • ノンブロッキングなhttpクライアントの実装(comming soon)

本エントリでは、それぞれの機能について見ていく。

return の実装

これまで以下のようなコードは、初見だと意図しない挙動をする。

Nginx.echo "OK"
Nginx.return Nginx::DECLINED  # ここでプログラムからreturnすると思いがち
Nginx.echo "NG"
# => "OKNG"

対応方法として、以下のようにLambdaで記述していた。

Nginx.return -> do
  Nginx.echo "OK"
  return Nginx::DECLINED
  Nginx.echo "NG"
end
# => "OK"

v2からは以下のように記述可能

Nginx.echo "OK"
Nginx.return Nginx::DECLINED
return
Nginx.echo "NG"
# => "OK"

Nginx::Async.sleep の実装

ノンブロッキングsleepの実装。1 nginx workerプロセスの動きを説明する。

  • これまでのngx_mruby

    image

  • v2のngx_mruby

    image

このように、処理ができる。 つまり、何か重い処理やや外部コマンドを実行するようなときにsleepさせて別の処理を実行するということが可能となる。

実際の実装や動作については、以下が非常に参考になる。

ノンブロッキングについては、以下の記事が非常に参考になった。

ノンブロッキングなhttpクライアントの実装(comming soon)

社内で @matsumotory さんから聞いた情報によると、ノンブロッキングなhttpクライアントの機能が実装されるとのこと。

これは、非常に便利で極力な機能で、例としてはnginxの挙動を外部APIの実行結果を元に変更するようなことをしたい場合に、これまでhttpリクエストの処理中はブロッキングされていたがv2から実装される機能を利用するとその間は別の処理を行うことができるため全体的に高速に動作するようになる。

私が担当するプロダクトについては、nginxの挙動を変更するためのパラメータをMySQLのデータベースからRedisにキャッシュしつつ取得している。その為、nginx側にビジネスロジックを持っていてそれが変更になることによって同様の変更をする必要がある。ビジネスロジックをもつhttpベースのAPIが存在するため、そちらから取得すればビジネスロジックの変更に強いし今回のノンブロッキング化が入ることで実現の可能性がある。

これと関連して、mruby-mysqlやmruby-redisなどブロッキングが発生する処理についてもノンブロッキングなメソッドを新たに実装することによって、ngx_mrubyとの組み合わせで同様な効果が得られるため今後の進化の幅が広がったと思える。