【Linux】netstatコマンドで TIME_WAIT が大量に発生する

■ はじめに

 * 負荷テストを行っている時に、netstatコマンドを入力したら、
   大量に TIME_WAIT が表示された。
   (今回は、データベースとの接続で大量に発生していた)

■ どんな事になるのか?

 OSでは使用できるポート(「エフェメラル ポート / 動的 ポート」)の範囲が決まっている。
あまりにも、大量に TIME_WAIT が発生すると、ポートが枯渇して通信ができなくなる
 => netstatコマンド(オプション -o)で観察すると、
    タイマー(デフォルト60秒)が切れると、TIME_WAIT が消えていく
エフェメラル ポート / 動的 ポート」については、以下の関連記事を参照のこと。
https://blogs.yahoo.co.jp/dk521123/34703712.html

■ ポートの数を調べるには?

ip_local_post_range を参照する
cat /proc/sys/net/ipv4/ip_local_port_range
32768	60999

上記の場合
60999 - 32768 + 1 = 28232 が使用可能
現在のTIME_WAITの発生数をカウントする
sudo netstat -anp|grep TIME_WAIT|wc -l
2134

■ 対応策

 * net.ipv4.tcp_tw_reuse / net.ipv4.tcp_fin_timeout でチューニングする

`カーネルパラメータ`説明備考
net.ipv4.tcp_tw_reuseTIME_WAIT状態の接続を新しい接続で再利用するか1:再利用。0:再利用しない
net.ipv4.tcp_fin_timeoutFIN-WAIT-2状態を何秒保持してからTIME_WAIT状態にするか極端に小さい(1秒)と問題が行る可能性あり。10~30秒が妥当

手順例

[1] /etc/sysctl.conf を修正し、net.ipv4.tcp_tw_reuse / net.ipv4.tcp_fin_timeoutを設定する
sudo vi /etc/sysctl.conf
~~~~
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
~~~~
[2] sysctl -p で、カーネルパラメータを反映する
sudo sysctl -p

補足:「net.ipv4.tcp_tw_recycle」について

 * 「net.ipv4.tcp_tw_recycle」は、いじらない方がいい
 * Linux バージョン4.12から廃止
http://d.hatena.ne.jp/pullphone/20120511/1336722675
https://qiita.com/tmshn/items/b49f1b51bfc472968b30


関連記事

Linux】【Windowsnetstat ~ ネットワーク統計や状態を確認 ~

https://blogs.yahoo.co.jp/dk521123/34848875.html

トランスポート層TCP / UDP

https://blogs.yahoo.co.jp/dk521123/31343326.html

【ネットワーク】ポート番号

https://blogs.yahoo.co.jp/dk521123/34703712.html