CLOSE_WAITのセッションを早く消す方法


原因はおそらくwebサーバ~DBサーバ間のセッションがネットワーク的に不安定だったからだと思うけど、DBサーバで netstat -an すると 大量の CLOSE_WAIT のセッションが残ってしまって、MySQL の最大コネクション数にまで達してしまってwebの表示が出来なかった。

CLOSE_WAIT をいきなり消すことは出来ないので、早めに消えるようにしたいときは

tcp_keepalive_time
TCPセッションが確立されて検査が実施されるまでの時間
時間になると tcp_keepalive_intvl と tcp_keepalive_probes の値にしたがって検査を実施する
tcp_keepalive_intvl
次の検査を実行するときの待ち時間
tcp_keepalive_probes
検査の回数

のそれぞれの値を小さくしてあげればよい。

変更方法は vi で :wq すると error がでておこられるので、echo を使う。反映に再起動などはいらない。

# echo 10 > /proc/sys/net/ipv4/tcp_keepalive_time

# echo 2 > /proc/sys/net/ipv4/tcp_keepalive_probes

# echo 3 > /proc/sys/net/ipv4/tcp_keepalive_intvl

デフォルト値と変更後の値と CLOSE_WAIT が切れるまでの時間を表にする

項目 デフォルト 変更後
tcp_keepalive_time 7200(sec) 10(sec)
tcp_keepalive_probes 9(回) 2(回)
tcp_keepalive_intvl 75(sec) 3(sec)
TCPセッションが確立して最短で落ちるまでの時間 7200+9*75=7875(sec) (2時間10分くらい) 10+2*3=16(sec)

緊急時だったのでこのくらいにして、期待通りに CLOSE_WAIT がどんどん消えていった。

今でもこの設定のまま様子見だけど、TCPセッションが確立されているものを切ってしまうわけではないので、問題はないのでは?と勝手に思っている

上記は一時的な反映をしたい時の実施方法で、OS再起動で消えてしまう。

消えないためには、

# vi /etc/sysctl.conf

net.ipv4.tcp_keepalive_time = 10

net.ipv4.tcp_keepalive_probes = 2

net.ipv4.tcp_keepalive_intvl = 3

を追記

# sysctl -w

変更を反映

# sysctl -p

確認

のようにする