DC内通信のHTTP/2化を検討する
こんにちは、インフラストラクチャ部の後藤です。
懲りずにHTTP/2の記事です。
HTTP/2を実サービスに投入するのには様々な障壁があり、議論が足りてない部分だと感じています。
- サイトのHTTPS化
- TLS ALPN, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 サポート
- モニタリング・監視
- Dependency Based PriorityとRUM
- コネクションの生存時間が長く、運用上のDNSを用いたサーバ切り替えと相性が悪い(GOAWAY出せるものもあるが)
- ELBを使用している場合はTCPで利用する必要がある
そもそもL7ネットワーク機器が対応していないという場合もあるかとおもいます。
そこで、今回は比較的容易なDC内のHTTP通信をHTTP/2化することを考えます。
DC内HTTP通信のHTTP/2化
DC内でサーバ間のHTTP/2通信であれば、h2c(平文での通信)が出来ますので導入時に考えることが少なくなります。また、接続のコントロールや部分導入も比較的容易です。
DC内でHTTP通信が行われているところといえば、まずProxy - Applicationサーバ間が考えられます。簡単な図で示すと、以下の"ここ"の部分です。
今回はProxyとApplicationサーバにnghttp2のnghttpxを導入し、サーバ間通信のHTTP/2化を行いました(本番導入はしてません)。nghttpx間は平文のHTTP/2(h2c)で通信します。
Proxy側
nghttpx
1 2 3 4 |
$ nghttpx --http2-bridge -f unix:/var/tmp/sock --backend-no-tls --frontend-no-tls -b app1,3000 -b app2,3000 -b app3,3000 |
nginx.conf
1 2 3 4 5 6 7 8 9 10 11 |
upstream local_nghttp2 { server unix:/var/tmp/sock; } server { listen 80 default_server; location / { proxy_pass http://local_nghttp2/; proxy_set_header host $host; } ... |
App側
nghttpx
1 |
$ nghttpx --frontend-no-tls -f *,3000 -b unix:/var/tmp/sock |
nginx.conf
1 2 3 4 |
server { listen 80 default_server; listen unix:/var/tmp/sock; ... |
簡単な計測
Apache Benchで簡単に測定を行います。
今回は、Proxy - Applicationサーバを1対1とし、Appサーバは静的なページを返す簡単なものにしています。
(同一HTTPヘッダのみを扱うため、通常用途よりHPACK効率が有利に働いてるかとは思います)
http1.1でproxyする場合
1 2 3 |
$ ab -n 50000 -c 100 http://proxy-dev/use-http1/ ... Time taken for tests: 4.784 seconds |
http2でproxyする場合
1 2 3 |
$ ab -n 50000 -c 100 http://proxy-dev/use-http2/ ... Time taken for tests: 4.053 seconds |
単純な計測であるが、何度か測定してもHTTP/2を利用したほうが多少早いという結果となりました。
DC内ネットワークのサーバ間のRTTは非常に小さく、HTTP/1.1でもTCP 3ウェイハンドシェイクやスロースタートの影響は大きくないのでHTTP/2により劇的に改善はしませんでした。もう少しRTTのかかるネットワークだとより効力を発揮しそうです。
今回は使用するコンテンツが大きくなかったというのもありますが、トラフィックを計測するとHPACKによるトラフィック削減は一定の効果があるように感じました。
まとめ
今回はDC内のサーバにnghttpxを導入し、Proxy - Applicationサーバ間のHTTP通信をHTTP/2で行うようにしました。
Apache Benchを用いて簡単に計測を行いました。サーバ間のRTTは非常に小さいため大きくは改善出来なかったものの、一定の効果が得られました。