状況は次のとおりです。
http client ----> corporate firewall ----> http server
キープアライブにより、サーバーとクライアントはTCP接続を開いたままにし、クライアントはHTTPリクエストに接続プールを使用します。
ファイアウォールには、1時間後に長期のTCP接続を「強制終了」するルールがあります。問題は、HTTPクライアントがTCP接続が破壊されたことを検出せず、一定期間後にクライアントが「ハング」したように見えた、本質的に無効な接続を再利用しようとしたことです。おそらく新しい接続が確立されたため、要求がハングし、次の要求が機能しました。
ここでの問題は、 HTTPクライアントがTCP接続を検出できなかった方法でファイアウォールがTCP接続を強制終了するメカニズムは何ですか。私はいくつかの方法でこの動作をローカルで再現しようとしました:
- VyosルーターのTCP接続を強制終了し、クライアント側のWiresharkがTCP FIN-ACKをキャプチャしました。OK
- WindowsのTCPViewでTCP接続のクライアント側を強制終了し、Wiresharkがクライアント側でTCP RSTを検出しました。OK
- クライアント側ファイアウォールへの接続が確立された後にポートをブロックすると、ソケットリセット例外が発生しました。OK
サーバー側にWiresharkダンプがあり、ファイアウォールがFINまたはRSTを送信しているかどうかを確認しようとしましたip.dst==serverip && (tcp.flags.reset==1 || tcp.flags.fin==1)
が、何も表示されませんでした。
さらに、クライアント側のWiresharkキャプチャでは、HTTPリクエストが送信され、その後に数十のTCP再送信が続き、最終的にはどこにも送信されないという問題が示されています。
HTTPクライアントはJavaネイティブおよび/またはJetty HTTPクライアント(両方を試しました)であり、どちらも無効なTCP接続を検出できませんでした。動作をローカルで再現したいのですが、ファイアウォールが接続を強制終了しているので、どのような問題があるのかわからないので、考えられる答えを探しています。