原因はおそらく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
確認
のようにする