以前書いたとおり、ApacheではリバースプロキシでバックエンドとHTTP2通信することができます。
Nginxの場合は、開発者のメーリングリストでGoogleの人が書いてる「ngx_http_v2_upstream」パッチを利用することでバックエンド(upstream)とHTTP2通信することが出来るようになります。
パッチ
- [PATCH 01 of 14] Output chain: propagate last_buf flag to c->send_chain()
- [PATCH 02 of 14] Upstream keepalive: preserve c->data
- [PATCH 03 of 14] HTTP/2: add debug logging of control frames
- [PATCH 04 of 14] HTTP/2: s/client/peer/
- [PATCH 05 of 14] HTTP/2: introduce h2c->conf_ctx
- [PATCH 06 of 14] HTTP/2: introduce stream->fake_connection
- [PATCH 07 of 14] HTTP/2: introduce ngx_http_v2_handle_event()
- [PATCH 08 of 14] HTTP/2: add HTTP/2 to upstreams
- [PATCH 09 of 14] Proxy: add "proxy_ssl_alpn" directive
- [PATCH 10 of 14] Proxy: always emit "Host" header first
- [PATCH 11 of 14] Proxy: split configured header names and values
- [PATCH 11 of 14] Proxy: split configured header names and values
- [PATCH 12 of 14] Proxy: add HTTP/2 support
- [PATCH 13 of 14] Proxy: add "proxy_pass_trailers" directive
- [PATCH 14 of 14] Cache: add HTTP/2 support
ビルド
環境はUbuntu16.04
$ hg clone http://hg.nginx.org/nginx/ $ cd ./nginx $ hg update -r 7039 # 順番にパッチを当ててく $ patch -p1 < ./1.patch ... $ ./auto/configure --with-http_ssl_module --with-http_v2_module $ make #今回はインストールしてしまう $ sudo make install
設定
proxy_http_versionに2.0が指定できるようになります。
proxy_passにhttp://を指定すると、h2cダイレクトでバックエンドと接続しに行きます
(証明書は適当に準備)
#nginx.conf proxy_http_version 2.0; upstream backend { server 127.0.0.1; } server { listen 443 ssl http2; server_name localhost; ssl_certificate /home/yuki/server.crt; ssl_certificate_key /home/yuki/server.key; location / { proxy_pass http://backend/test; } }
その他、h2cダイレクトではなくhttpsでプロキシする際に、ALPNを使うように出来るようですがちょっと動作が怪しいようです....
proxy_ssl_alpn on;
動作確認
バックエンドはh2cで接続できるようにしておきます。
#nginx.conf server { listen 80 http2; server_name localhost; }
ブラウザでサーバにアクセスすると、バックエンド(/proxy/)もHTTP/2.0で接続できている事が確認できました
$ tail /var/log/nginx/access.log 127.0.0.1 - - [02/Jul/2017:16:36:40 +0000] "GET /proxy/ HTTP/2.0" 404 571 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36" 192.168.0.104 - - [02/Jul/2017:16:36:40 +0000] "GET / HTTP/2.0" 404 571 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"