サーバーの1つを新しいネットワーク接続の一定のストリームでヒットすることでストレステストしています。tcp_fin_timeout
は60に設定されているため、毎秒100リクエストのような一定のストリームを送信すると、 TIME_WAIT
状態で6000(60 * 100)接続のローリング平均を確認してください。これは発生していますが、タイマーを確認するためにnetstat
を調べます(-oを使用)。次のような接続が表示されます。
TIME_WAIT timewait (0.00/0/0)
タイムアウトの期限が切れたが接続がまだハングしている場合、結局接続が不足します。これらの接続がクリーンアップされない理由を誰かが知っていますか?新しい接続の作成を停止すると、最終的には消えますが、常に新しい接続を作成していますが、そうではありませんが、カーネルがそれらをクリーンアップする機会を得ていないようです。接続の有効期限が切れたらすぐに接続を削除するために設定する必要のある他の構成オプションはありますか?
サーバーはUbuntuを実行しており、私のWebサーバーはnginxです。また、接続追跡を備えたiptablesがあります。これらのTIME_WAIT
接続が存続するかどうかは不明です。
マークありがとう。
私はしばしば自分自身を疑問に思っていたので、この問題は興味深いものでした。私はいくつかのテストを行い、いくつかの興味深い結果を見つけました。サーバーへの接続を1つ開いて60秒待つと、常にクリーンアップされました(0.00/0/0にはなりませんでした)。 100個の接続を開いた場合、それらも60秒後にクリーンアップされました。 101個の接続を開いた場合、あなたが月経を行った状態で接続が表示され始めます(これも以前に見たものです)。また、fin_timeoutの設定に関係なく、約120秒または2xMSL(60)が続くようです。カーネルのソースコードを少し掘り下げて、「理由」だと私が信じているものを見つけました。 「サイクル」ごとに発生するソケットリーピングの量を制限しようとするコードがあるようです。サイクル周波数自体は、HZに基づくスケールで設定されます。
linux-source-2.6.38/include/net/inet_timewait_sock.h:
35 #define INET_TWDR_RECYCLE_SLOTS_LOG 5
36 #define INET_TWDR_RECYCLE_SLOTS (1 << INET_TWDR_RECYCLE_SLOTS_LOG)
37
38 /*
39 * If time > 4sec, it is "slow" path, no recycling is required,
40 * so that we select tick to get range about 4 seconds.
41 */
42 #if HZ <= 16 || HZ > 4096
43 # error Unsupported: HZ <= 16 or HZ > 4096
44 #Elif HZ <= 32
45 # define INET_TWDR_RECYCLE_TICK (5 + 2 - INET_TWDR_RECYCLE_SLOTS_LOG)
46 #Elif HZ <= 64
47 # define INET_TWDR_RECYCLE_TICK (6 + 2 - INET_TWDR_RECYCLE_SLOTS_LOG)
48 #Elif HZ <= 128
49 # define INET_TWDR_RECYCLE_TICK (7 + 2 - INET_TWDR_RECYCLE_SLOTS_LOG)
50 #Elif HZ <= 256
51 # define INET_TWDR_RECYCLE_TICK (8 + 2 - INET_TWDR_RECYCLE_SLOTS_LOG)
52 #Elif HZ <= 512
53 # define INET_TWDR_RECYCLE_TICK (9 + 2 - INET_TWDR_RECYCLE_SLOTS_LOG)
54 #Elif HZ <= 1024
55 # define INET_TWDR_RECYCLE_TICK (10 + 2 - INET_TWDR_RECYCLE_SLOTS_LOG)
56 #Elif HZ <= 2048
57 # define INET_TWDR_RECYCLE_TICK (11 + 2 - INET_TWDR_RECYCLE_SLOTS_LOG)
58 #else
59 # define INET_TWDR_RECYCLE_TICK (12 + 2 - INET_TWDR_RECYCLE_SLOTS_LOG)
60 #endif
61
62 /* TIME_WAIT reaping mechanism. */
63 #define INET_TWDR_TWKILL_SLOTS 8 /* Please keep this a power of 2. */
The number of slots is also set here:
65 #define INET_TWDR_TWKILL_QUOTA 100
実際のtimewaitコードでは、引用符を使用してTIME_WAIT接続の強制終了を停止している場所を確認できます。
linux-source-2.6.38/net/ipv4/inet_timewait_sock.c:
213 static int inet_twdr_do_twkill_work(struct inet_timewait_death_row *twdr,
214 const int slot)
215 {
...
240 if (killed > INET_TWDR_TWKILL_QUOTA) {
241 ret = 1;
242 break;
243 }
HZが何に設定されているのかについての詳細情報はこちらです: http://kerneltrap.org/node/5411 しかし、それは珍しいことではありませんそれを増やします。ただし、通常はtw_reuse/recyclingを有効にしてこのバケット/クォータメカニズムを回避するのがより一般的だと思います(これについて読んだので、混乱するようですが、HZを増やすと、はるかに安全でクリーンなソリューションになります)。私はこれを回答として投稿しましたが、それを修正するための「正しい方法」とは何かについて、ここでもっと議論があると思います。興味深い質問をありがとう!
net.ipv4.tcp_fin_timeoutのデフォルトは60秒です。ソケットがこの制限よりもTIME_WAIT長く留まる傾向がある理由は、私にははっきりしていません。
tcp_tw_recycleは壊れているとのことですが、使っていないのでわかりません。おそらくtcp_tw_reuseを1に設定する必要がありますが、これによりNATで問題が発生する可能性があります。