poll()
最近、私は本番環境でデータベースサーバーがクラッシュしたときに接続されたクライアントが最大2時間中断される問題(libpqクライアントライブラリの呼び出しの長い待ち時間)を追跡するのにかなりの時間を費やしました。問題をより深く掘り下げながら、中断されたTCP接続をタイムリーに確認するには、これらのカーネルパラメータを下に調整する必要があることに気づきました。
net.ipv4.tcp_keepalive_time = 7200 net.ipv4.tcp_keepalive_probes = 9 net.ipv4.tcp_keepalive_intvl = 75 net.ipv4.tcp_retries2 = 15
上記の4つの値はUbuntu 12.04システムから取得され、これらのデフォルト値は現在のバージョンでは変更されていないようですLinuxカーネルのデフォルト。
設定は、既存の接続を開いたままにする方向に大きく偏向されており、接続保持プローブに対して非常に目立つようです。 AIUI、tcp_keepalive_time
デフォルトの2時間は、リモートホストからの応答を待っている間に2時間忍耐を持って待ってから、接続維持プローブを開始して接続がまだ有効であることを確認することを意味します。その後、リモートホストがkeepaliveプローブに応答しない場合、これらのkeepaliveプローブはtcp_keepalive_probes
75秒間隔()で9回(tcp_keepalive_intvl
)再試行されるため、接続が実際に切断されたことを確認する前にさらに11分待つ必要があります。
これは現場で見たものと一致します。たとえば、psql
リモートPostgreSQLインスタンスに接続されたセッションを開始すると、一部のクエリが応答を待っています。
SELECT pg_sleep(30);
その後、リモートサーバーがひどく死んで(たとえば、そのコンピュータへのトラフィックが失われる)、psqlセッションが切断されたことを発見するまでに最大2時間11分待つことがわかりました。想像できるように、これらのデフォルト設定は、データベースフェイルオーバーイベント中にデータベースと通信するコードに深刻な問題を引き起こします。取っ手を下げるとたくさんのお役に立ちます!私がいることがわかりました。一人じゃないこれらのデフォルト値を調整することをお勧めします。
だから私の質問は次のようになります
- この基本的な状態はどれくらい持続しましたか?
- これらのTCP設定をデフォルトに設定した元の理由は何ですか?
- Linuxディストリビューションでこれらのデフォルト値を変更しましたか?
これらの設定の根拠に関する他の記録や視点には大変感謝いたします。
答え1
RFC 1122セクション4.2.3.6に規定されている接続保持時間は、デフォルトでは2時間未満に設定しないでください。