タイトルの通り、ngx_mrubyのhttpモジュールとstreamモジュール両方で、mrubyによる動的Listener設定をサポートしました。
動的Listenerとは、nginxのlistenの設定をmrubyで書いて、起動時に動的に設定を読み込めるようにできる機能です。以下の例を見た方が分かりやすいかと思います。
worker_processes 1;
events {
worker_connections 30000;
}
daemon off;
master_process off;
error_log logs/error.log debug;
stream {
upstream dynamic_server {
server 127.0.0.1:8080;
}
server {
mruby_stream_server_context_code '
(20001..30000).each { |port| Nginx::Stream.add_listener({address: port.to_s}) }
';
mruby_stream_code '
c = Nginx::Stream::Connection.new "dynamic_server"
c.upstream_server = "127.0.0.1:#{Nginx::Stream::Connection.local_port * 2}"
';
proxy_pass dynamic_server;
}
}
http {
server {
mruby_server_context_handler_code '
s = Nginx::Server.new
(20001..30000).each { |port| s.add_listener({address: (port * 2).to_s}) }
';
location /mruby {
mruby_content_handler_code 'Nginx.rputs "#{Nginx::Connection.new.local_port} sann hello"';
}
}
}
このように書くと、nginxのTCPロードバランサが20001ポートから30000ポートまでListenした上で、接続のあったポート番号の数値の2倍のポート番号へTCPプロキシします。さらに、nginxのhttp側では20001ポートから30000ポートの2倍のポート番号でListenし、そのポート番号に応じてhelloを返します。
この設定でnginxを起動すると、これまでlistenディレクティブを沢山並べる必要があり、CRubyとerbなどを使ってプロビジョニング時にゴニョゴニョ書かなければいけなかった処理を、スッキリとmrubyで書くことができるようになります。また、ポート番号をデータベースやホストの状態に合わせていい感じにリッスンするような実装も可能でしょう。
$ netstat -lnpt | grep nginx | wc -l
20000
上記のような設定でcurlでアクセスすると、以下のようにレスポンスが返ってきます。
[ubuntu@ubuntu-xenial:~]$ curl http://127.0.0.1:20001/mruby
40002 sann hello
[ubuntu@ubuntu-xenial:~]$ curl http://127.0.0.1:20002/mruby
40004 sann hello
[ubuntu@ubuntu-xenial:~]$ curl http://127.0.0.1:29999/mruby
59998 sann hello
ふむふむなるほどべんり!
ということで皆様是非ngx_mruby v1.20.0の新機能をご活用ください。
github.com