ngx_mruby の Nginx::Async::HTTP でハマったとこ
ngx_mruby にはノンブロッキングで httpリクエストできるNginx::Async::HTTP
というものが用意されている。
外部からリクエストを受け付ける nginx(便宜上frontとする) とfrontからリクエストを受け付けるnginx(便宜上apiとする)を用意して Nginx::Async::HTTP
を試してみた。
front の設定
user nginx; worker_processes 1; load_module modules/ndk_http_module.so; load_module modules/ngx_http_mruby_module.so; events { worker_connections 1024; } master_process off; http { include mime.types; server { listen 80; server_name localhost; location /sub_req_proxy_pass { proxy_pass http://nginx-api:8080/api; } location /front { mruby_rewrite_handler_code ' Nginx::Async::HTTP.sub_request "/sub_req_proxy_pass" res = Nginx::Async::HTTP.last_response Nginx.rputs res.body '; } } }
api の設定
user nginx; worker_processes 1; load_module modules/ndk_http_module.so; load_module modules/ngx_http_mruby_module.so; events { worker_connections 1024; } master_process off; http { include mime.types; server { listen 8080; server_name localhost; location /api { mruby_content_handler_code ' Nginx.echo "Hello World" '; } } }
上記の設定の nginx を立てて front にリクエストしたところ、レスポンスが返ってこなかった。
$ curl localhost:8000/front curl: (52) Empty reply from server
ngx_mruby/nginx.conf at master · matsumotory/ngx_mruby · GitHub
この辺りを眺めているとサブリクエストでは mruby_output_body_filter
ディレクティブをつけているので以下のようにサブリクエストのlocationディレクティブに mruby_output_body_filter
ディレクティブを追加するとレスポンスが返ってくるようになった
location /sub_req_proxy_pass { proxy_pass http://nginx-api:8080/api; mruby_output_body_filter_code ''; }
$ curl localhost:8000/front Hello World
知識不足でなぜ mruby_output_body_filter
ディレクティブ が必要なのかは理解できていないが、Nginx::Async::HTTP
を利用してサブリクエストを行う場合、サブリクエストのlocationディレクティブで mruby_output_body_filter
ディレクティブが必須のようだった