LINUX忘却録-リナックス(主にdebian)の覚書や、解説を書いています。
[7]  [8]  [9]  [10]  [11]  [12]  [13]  [14]  [15]  [16]  [17
Linux (カーネル 2.4.23)では、ブロッキングモードで、Connectは、通常平均 180秒でタイムアウトします。
これは、接続の時にクライアント側が、サーバに対してSYNを送信し、ACKが帰ってきたら接続成功なのですが、このACKが帰ってこない時に、クライアントは、SYNの再送を試みます。
このとき再送は、以下のように5回再送されます。

最初のSYN送信    (0秒経過)
3秒経過してACKが、戻らないとき、SYN(1)を再送します。  (3秒経過)
また、6秒経過してACKが、戻らないとき、SYN(2)を再送します。  (9秒経過)
また、12秒経過してACKが、戻らないとき、SYN(3)を再送します。  (21秒経過)
また、24秒経過してACKが、戻らないとき、SYN(4)を再送します。  (45秒経過)
また、48秒経過してACKが、戻らないとき、SYN(5)を再送します。  (93秒経過)
また、96秒経過してACKが、戻らないとき、ここでタイムアウトが発生します
                                                              (189秒経過)


Linuxでは、この再送がデフォルト(初期設定)で、5回再送となっているので、タイムアウトに189秒かかります。

ACKが戻らない理由としては、以下の場合が考えられます。

  • ローカルまたはピアのネットワークケーブル断線
  • 途中経路の HUB 故障・ルータ故障
  • ピアのマシンが故障や停電でダウン
  • 指定した IP アドレスに、そもそもマシンが存在しない  

自分で、再接続や、エラー処理を行っている時、この時間を短くしたい事がたまにあります。
この場合、再送回数を減らす事で、対応可能です。


/proc/sys/net/ipv4/tcp_syn_retries の値を変更できます。(デフォルト5回、最大255以下)

0に設定すると、再送が行われません。つまり3秒でタイムアウト
1に設定すると、一回再送が行われます。つまり9秒でタイムアウト
2に設定すると、一回再送が行われます。つまり21秒でタイムアウト
3に設定すると、一回再送が行われます。つまり45秒でタイムアウト
4に設定すると、一回再送が行われます。つまり93秒でタイムアウト
5に設定すると、一回再送が行われます。つまり189秒でタイムアウト


3*2^(N-1)秒の間隔(NはN回目のSYN)を空けてSYNパケットが送信される


上記の対応は、一般的な対象方法です。
しかし、サーバの処理が重すぎて、コネクトに失敗するとき等の、タイムアウトが長すぎる
問題は、回避できません

この問題を回避するには、今のところ2つの方法しかなさそうです。

  1. ノンブロッキングとSELECTを使用して、自分で接続タイムアウト処理を書く。
  2. スレッドのタイムアウト処理を使って回避する。 

 

PR
フリーエリア
Copyright © LINUX忘却録 All Rights Reserved.