ロードバランサーの背後に2つのApacheWebサーバーがあり、mod ajpを介して2つの(JBoss)アプリケーションサーバーに接続されています。
これらのWebサーバーには、モバイルデバイスはREST APIを介して接続します。
私たちのパフォーマンステストでは、mod_reqtimeoutから来ていると特定した多くのNonHttpResponse:エラーにすぐに遭遇しました:
[Mon Mar 16 14:42:49.324705 2015] [reqtimeout:info] [pid 27914:tid 140628428449536] [client 1.2.3.4:48280] AH01382: Request header read timeout
...これは次のように構成されています。
<IfModule reqtimeout_module>
RequestReadTimeout header=10-20,minrate=500
RequestReadTimeout body=10,minrate=500
</IfModule>
これらの値をに増やすことで、これらのエラーを取り除くことができました。
RequestReadTimeout header=20-60,minrate=100
しかし、これは解決策にはなりません。同時ユーザーが増えると、問題が再び発生したためです(300人の同時ユーザーにサービスを提供できる必要があります。100人は問題なく動作し、300人では10,000を超えるリクエストヘッダーの読み取りタイムアウトが発生しました。エラー)。 mod_reqtimeoutが(何もしない多くの開いている接続に対して)slowloris攻撃が進行中であるという結論に導くのは、apaches KeepAlive、mod_ajp構成、およびmod_reqtimeoutの相互作用であると思われます。これらのパラメーターの調整について、ご協力をお願いします。
追加の問題は、Webサーバーとアプリケーションサーバー間のファイアウォールです。これは、開いているアイドル状態の接続を強制終了すると思われます。これを解決するためにKeepAliveを完全に非アクティブ化することについて読みましたが、前述したように、すべてのクライアントはモバイルデバイスであるため、おそらくそれはオプションではありません(?)。
その他の構成(の一部)は次のとおりです。
worker.properties:
worker.list=server
worker.maintain=60
worker.server.type=ajp13
worker.server.Host=server
worker.server.port=15869
worker.server.socket_keepalive=True
worker.server.connection_pool_timeout=600
worker.server.ping_mode=A
worker.server.connection_ping_interval=60
mod_prefork:
<IfModule prefork.c>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
#MaxClients 256
MaxClients 300
MaxRequestsPerChild 0
</IfModule>
mainserver.conf:
Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 15
ssl.conf(モバイルデバイスはssl経由で接続します):
Timeout 1200
KeepAlive On
MaxKeepAliveRequests 0
KeepAliveTimeout 10
本質的にリバースプロキシのように見える「プリフォーク」MPMを使用しているのは珍しいことですが、ハイブリッド「ワーカー」MPMの方がスケーラビリティが優れていますが、問題はありません。
DoS緩和は通常、クライアント要求を終了するフロントエンドデバイスで(ISPによってではない場合)最適に処理されます。説明から、これは負荷です。 -Apacheではなくバランサー。有能なロードバランサーはすべてHTTP対応(つまり「レイヤー7」)であり、これによりHTTPリクエストがバッファリングされる可能性があります。これは、ロードバランサーがHTTPSを終了している場合にも当てはまりますが、ロードバランサーが単にHTTPS接続を中継している場合は当てはまりません(HTTP要求をバッファリングすることはできないため)。ロードバランサーが単純な「レイヤー3/4」NATタイプのロードバランサーである場合も、適用されません。
タイムアウトの考えられる原因について:
KeepAliveTimeout
はRequestReadTimeout
ヘッダーの読み取りタイムアウトと同じです。着信クライアント要求/ヘッダーの途中で、キープアライブタイムアウトに達する競合が発生する可能性があります。これを再現しようとすると、AH01382エラーに加えて、AH01991(SSL入力フィルターの読み取りに失敗しました)とAH00567(要求に失敗しました:ヘッダーの読み取りエラー)も発生します。しかし、これはすべての問題を説明するわけではありません。タイムアウトを再現するには:
$ openssl s_client -connect myhost:443
GET / HTTP/1.1
Host: myhost.whatever.com
[server reply goes here]
GET / HTTP/1.1
Host:
これをスクリプト化して簡単にすることができます。そうでない場合は、最初のリクエストとヘッダーを構成済みの10秒以内に入力/貼り付けしてから、と入力しますが、2番目のリクエストは完了しません次の10秒以内にリクエストを行うには、2番目のリクエストに対して少なくとも1つのフルライン(リクエスト)を送信してから、待つ必要があります。
KeepAliveTimeout(デフォルトは5秒)を減らすと役立つ場合があります。 KeepAliveTimeoutは、完全なリクエストを受信する時間であることに注意してください。次のステップは mod_log_forensic
。
AJPを介したバックエンドへの接続に関して、 Apache Balancer
configuration で「ping」を使用していますか?システムを正しく理解している場合、指定したTomcat構成は、ApachehttpdからTomcatへの接続には適用されません。 ここのオプション を参照してください。
/-> Apache httpd + ajp -\ /-> Tomcat/jboss
client -> load-balancer < > firewall <
\-> Apache httpd + ajp -/ \-> Tomcat/jboss