HAproxy シンプルなリバースプロキシは非常に遅い

HAproxy シンプルなリバースプロキシは非常に遅い

現在、いくつかの Web サイトのリバース プロキシとして機能する HAproxy マシンを設定しています。異なるマシンは物理的に接続されていないため、OpenVPN を使用してマシン間の VPN を作成しています。

技術的にはすべて正常に動作しています。ただし、プロキシを介してパイプするリクエストが非常に遅いという問題があります。最終的には完全な応答が得られますが、Jenkins ダッシュボードのようなものを受け取るまでに最大 5 分かかります。

私は、NGINX 経由で提供される単純な静的 HTML ページと、go で実装されたいくつかの REST API を試してみましたが、結果は常に同じでした。最終的にはデータは取得されますが、途方もない時間がかかります。

私の HAproxy 設定は次のとおりです:


  global
          log /var/run/log local0 info
          log /var/run/log local0 notice
          daemon
          maxconn 8000
          tune.ssl.default-dh-param 2048
          user nobody
          group nobody

  defaults
          log global
          option httplog
          option dontlognull
          mode http
          timeout connect 5s
          timeout client 1min
          timeout server 1min
          option forwardfor
          option http-server-close
          errorfile 400 /usr/local/etc/haproxy/errorfiles/400.http
          errorfile 403 /usr/local/etc/haproxy/errorfiles/403.http
          errorfile 408 /usr/local/etc/haproxy/errorfiles/408.http
          errorfile 500 /usr/local/etc/haproxy/errorfiles/500.http
          errorfile 502 /usr/local/etc/haproxy/errorfiles/502.http
          errorfile 503 /usr/local/etc/haproxy/errorfiles/503.http
          errorfile 504 /usr/local/etc/haproxy/errorfiles/504.http

  frontend http-in
          bind *:80
          bind *:443 ssl crt /usr/local/etc/haproxy/certs/foo.my.org.pem
          mode http
          use_backend jenkins if { hdr(host) -i foo.my.org }
          use_backend test if { hdr(host) -i bar.my.org }
          default_backend test

  backend jenkins
          server jenkins1 <vpn_ip>:8180
          mode http
          http-request set-header X-Forwarded-Port %[dst_port]
          http-request add-header X-Forwarded-Proto https if { ssl_fc }
          reqrep ^([^\ :]*)\ /(.*)     \1\ /\2
          acl response-is-redirect res.hdr(Location) -m found
          rspirep ^Location:\ (http)://<vpn_ip>:8180/(.*)   Location:\ https://foo.my.org:443/\2  if response-is-redirect

  backend test
          server web01 <vpn_ip>:80

追加情報:

  • 関係するすべてのマシンはデータセンターに設置されており、1G/1Gインターネット接続を備えています。
  • すべてのマシンはFreeBSD 11 64ビットで動作します
  • すべてのマシン上の OpenVPN バージョン 2.4.4
  • HAproxy バージョン 1.7.9
  • OpenVPNはTCPモードで動作します
  • JenkinsのHAproxyバックエンド設定は、Jenkins ドキュメントしかし、前述のように、単なる静的 HTML コンテンツ Web サーバーと REST API Web サービスでも同じ問題が発生します。

Jenkins サイトにアクセスしたときの HAproxy ログを次に示します。

Feb 27 01:32:24 hostname haproxy[5539]: 213.144.130.227:60243 [27/Feb/2018:01:32:24.093] http-in~ jenkins/jenkins1 0/0/13/134/161 302 153 - - ---- 5/5/0/0/0 0/0 "GET /jenkins HTTP/1.1"
Feb 27 01:32:24 hostname haproxy[5539]: 213.144.130.227:19404 [27/Feb/2018:01:32:24.255] http-in~ jenkins/jenkins1 0/0/25/174/212 200 4492 - - ---- 5/5/0/0/0 0/0 "GET /jenkins/ HTTP/1.1"
Feb 27 01:32:25 hostname haproxy[5539]: 213.144.130.227:16321 [27/Feb/2018:01:32:25.330] http-in~ jenkins/jenkins1 0/0/13/30/54 200 8560 - - ---- 6/6/4/4/0 0/0 "GET /jenkins/static/aeed77bb/scripts/yui/datasource/datasource-min.js HTTP/1.1"
Feb 27 01:32:25 hostname haproxy[5539]: 213.144.130.227:54637 [27/Feb/2018:01:32:25.330] http-in~ jenkins/jenkins1 0/0/27/29/58 200 7585 - - ---- 6/6/3/4/0 0/0 "GET /jenkins/static/aeed77bb/scripts/yui/autocomplete/autocomplete-min.js HTTP/1.1"Feb 27 01:32:25 hostname haproxy[5539]: 213.144.130.227:59247 [27/Feb/2018:01:32:25.361] http-in~ jenkins/jenkins1 0/0/25/16/51 200 9602 - - ---- 6/6/2/3/0 0/0 "GET /jenkins/static/aeed77bb/jsbundles/page-init.js HTTP/1.1"
Feb 27 01:32:25 hostname haproxy[5539]: 213.144.130.227:40637 [27/Feb/2018:01:32:25.332] http-in~ jenkins/jenkins1 0/0/38/18/81 200 16212 - - ---- 6/6/1/1/0 0/0 "GET /jenkins/static/aeed77bb/scripts/yui/menu/menu-min.js HTTP/1.1"
Feb 27 01:32:25 hostname haproxy[5539]: 213.144.130.227:10976 [27/Feb/2018:01:32:25.333] http-in~ jenkins/jenkins1 0/0/37/30/95 200 29110 - - ---- 6/6/0/0/0 0/0 "GET /jenkins/static/aeed77bb/scripts/hudson-behavior.js HTTP/1.1"
ログ ファイルには他に何も表示されません。エラーなどはありません。

これは OpenVPN が原因でしょうか?

編集1:その間、私は OpenVPN を使用せずに、HAproxy 構成で Web サーバーのパブリック IP アドレスを直接使用してこれをテストしました。結果はまったく同じでした。

答え1

ログには 5 分間の待機時間を説明するのに十分な情報は含まれていません (待機時間は 2 秒未満です) が、次のような点が目立ちます。

option http-server-close

これは、WAN リンクの反対側にあるバックエンドには適していません。この機能が実際に必要な場合は、バックエンド サーバーに対して非常に低いレイテンシ (ローカルなど) を持つ HAProxy 上に配置する必要があります。

タイマー値に大きなジッターがあることに注意してくださいTc。これは、ログ フィールドの 3 番目の値で、次のようになります。

Tq/Tw/Tc/Tr/Tt

したがって、最初のエントリでは0/0/13/134/161Tc値は 13 ミリ秒です。は Tcバックエンドへの接続を確立するために必要な時間です。したがって、ここでわかるのは、ラウンドトリップ ジッターがほぼ制御不能であり、あるケースではこの値のほぼ 3 倍に跳ね上がっているということです。これがバックエンド サーバーのリソース不足によって発生したのではないと仮定すると、これは OpenVPN を TCP モードで使用した結果である可能性が高く、パケット損失を示している可能性がありますが、必ずしもそうとは限りません。

TCP (HTTP) を TCP (OpenVPN) 内でトンネリングしています。これは、非対話型アプリケーションやジッターが重要でないアプリケーションでは通常は問題ありませんが、それ以外の場合は問題があります。(たとえば、TCP over TCP がなぜ悪いアイデアなのか潜在的なメルトダウン シナリオの 1 つについて議論するために、この設定をクリーンなネットワークで完全に避ける十分な理由ではありませんが、OpenVPN のせいではないと思いますが、TCP トンネルの遅延は UDP トンネルと同じ一貫性がありません。トンネルを介して ping を実行すると、このジッターが ping 応答時間に影響していることがわかります。

トンネルを UDP に変更すると、問題は解消されるはずです...ただし、このジッターの重要性とパフォーマンスへの影響は、TCP トンネルの使用による副作用であるという私の考えが正しいと仮定すると、 を使用することでおそらく誇張されることに注意してください。option http-server-closeでは、各リクエストで HAProxy とバックエンドの間に新しい接続を確立する必要があります。

OpenVPN トンネルが を使用して圧縮されている場合はcomp-lzo、転送時の潜在的なコスト削減よりもオーバーヘッドのほうが大きい可能性があるため、これも無効にすることを検討してください。

答え2

これはファイアウォール/NAT 構成の問題であることが判明しました。

ただし、この問題に遭遇した場合は、HAproxy コミュニティでさらにサポートを受けることができます。https://discourse.haproxy.org/t/reverse-proxy-very-slow-page-load/2172

関連情報