trusterdはHTTP/2クライアントとサーバ両方の機能を持っており、それらの機能は全てモジュールとして取り外し可能な設計にしています。
そのため、HTTP/2クライアント・サーバ機能をmrubyモジュールとして取り外して、他のアプリケーションにmruby経由で組み込めば、簡単にtrusterdのHTTP/2機能を利用することができます。
今回は、遊びとちょっとの真面目さで、ngx_mruby経由でnginxにtrusterdのHTTP/2サーバ機能を組込み、nginx起動時にnginxの内部情報HTTP/2サーバをforkして起動し、HTTP/2クライアントからnginxのバージョン情報を取り出してみました。
何いってるの?という感じですが、最後までお付き合い下さい。
ngx_mrubyにmruby-http2を組込み
trusterdのHTTP/2機能はmruby-http2として利用可能です。ですので、以下のようにngx_mrubyのbuild_conig.rbにモジュールを組み込む設定を書きましょう。下記を追記します。
conf.gem :github => 'matsumoto-r/mruby-simplehttp' conf.gem :github => 'mattn/mruby-http' conf.gem :github => 'trusterd/mruby-http2'
そしていつも通りngx_mrubyをビルドしてngx_mrubyを組み込んだnginxを作成します。簡単ですね。
nginx内部用HTTP/2サーバを起動する設定をnginx.confに書く
続いて、nginx.confに設定を書きます。
今回はworker起動時のフックであるmruby_init_worker_code
に以下のように書きました。関連箇所だけ書きます。
http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; mruby_init_worker_code ' root_dir = "/usr/local/trusterd" tls = HTTP2::Server.new({ :port => 8080, :document_root => "#{root_dir}/htdocs", :server_name => "nginx_internal_http2", :worker => "auto", :key => "#{root_dir}/ssl/server.key", :crt => "#{root_dir}/ssl/server.crt", :callback => true, }) # レスポンス生成処理でフックしてレスポンスデータをここで作成 tls.set_content_cb { tls.r.rputs Nginx.nginx_version } pid1 = Process.fork() { tls.run } '; server { listen 8079; server_name localhost; ・ ・ ・
これで、nginx起動時にtls使用のnginx_internal_http2というHTTP/2 Webサーバもforkして同時に起動することができそうです。
そして、HTTP/2リクエストを送ると、Nginx.nginx_version
というngx_mrubyのクラス・メソッドによってnginxのバージョン情報を得られそうですね。
起動させてレスポンスを確認する
では起動させてみましょう。
以下のようなプロセスの状態になりました。
matsumo+ 48189 0.5 0.0 36540 3756 pts/8 S+ 23:28 0:00 | \_ ./build/nginx/sbin/nginx matsumo+ 48190 0.0 0.0 36540 1644 pts/8 S+ 23:28 0:00 | \_ ./build/nginx/sbin/nginx matsumo+ 48191 0.0 0.0 36672 3080 pts/8 S+ 23:28 0:00 | \_ ./build/nginx/sbin/nginx matsumo+ 48192 0.0 0.0 36672 3080 pts/8 S+ 23:28 0:00 | \_ ./build/nginx/sbin/nginx matsumo+ 48193 0.0 0.0 36672 3064 pts/8 S+ 23:28 0:00 | \_ ./build/nginx/sbin/nginx matsumo+ 48194 0.0 0.0 36672 3068 pts/8 S+ 23:28 0:00 | \_ ./build/nginx/sbin/nginx
HTTP/2サーバがforkされて、今回はworker数を適当にautoにしたのでCPUコアの数だけ起動していますね。
では、外部からこのHTTP/2サーバにアクセスしてみましょう。
$ nghttp https://127.0.0.1:8080/ 1.7.7
起動中のnginxのバージョンを裏からHTTP/2経由で取得できました。
$ nghttp -v https://127.0.0.1:8080/ | grep server [ 0.008][NPN] server offers: [ 0.015] recv (stream_id=1, noind=0) server: nginx_internal_http2
serverヘッダもnginx_internal_http2になっています。
まとめ
ということで、今回はtrusterdのHTTP/2機能を取り外した上で、別のアプリに組み込んでHTTP/2機能を試す事に成功しました。また、アプリの内部の情報をHTTP/2で裏から取ることもできました。
今回はほぼ遊びですが、なんとなくもっとうまくやれば面白い事ができるんじゃないかという実感を得ました(得た気がしました)。
この機能を応用すると、ミドルウェア間での通信やデバイス間での通信などにHTTP/2を使って協調して動くような処理が可能かもしれませんね。
是非遊んでみてください。