1. ホーム

問題発見対応に失敗した

2022-02-22 07:42:24

問題の説明

zuul1.xの使用中に、httpclientのNoHttpResponseExceptionに対応する例外メッセージfailed to respondが表示されることがあります。

解決方法

クライアント側が nginx プロキシに接続するためのサービスとしての zuul に対応する設定は、以下の通りです。

zuul.host.max-per-route-connections=600
zuul.host.socket-timeout-millis=10000
zuul.host.connect-timeout-millis=10000
zuul.host.time-to-live=600000


そして、nginx は keepalive_timeout=180s を設定しているので、idle が 180s になったら、サーバーは切断されていることになります。この時点で、httpclientはプール内の接続を取得する際にNoHttpResponseExceptionを取得する可能性が高いです。

zuul.host.time-to-live を <= nginx の keepalive_timeout に設定する必要があります。
また、zuul.host.max-per-route-connectionsは実際の状況に応じて割り当て、あまり大きくならないようにする必要があります。

しかし、テストした結果、この現象はたまにしか発生せず、httpclientは接続が切断された後でも再接続を継続するように、内部でさまざまなメカニズムを使用しています。

<ブロッククオート

ほとんどの場合、コネクションマネージャーによって維持されている持続的な接続は、陳腐化します。つまり、接続がアイドル状態のときに、HttpClientがそのイベントに反応することなく、ターゲットサーバー側が接続をシャットダウンしてしまい、接続が半分閉じられた状態、つまり「stale」になってしまうのです。通常、これは問題ではありません。HttpClientは、プールから接続を解放する際に、接続の有効性を確認するためのいくつかの手法を採用しています。接続チェックが無効になっている状態で、古い接続を使ってリクエストメッセージを送信すると、通常は書き込み操作に失敗しますが、状況によっては書き込み操作が例外なしで終了し、その後の読み込み操作が-1 (end of stream) を返すことがあります。この場合、HttpClient は、リクエストは成功したが、サーバーが予期せぬエラーにより応答できなかったと考えるしかありません。この状況を改善する最も簡単な方法は、有効期限の切れた接続や、例えば 1 分以上アイドル状態だった接続を、一定時間後にプールから追い出すことです。この状況を改善する最も簡単な方法は、期限切れの接続や、1分以上アイドル状態であった接続を、一定期間活動しなかった後にプールから追い出すことです。