※ 以下、フィクションです。
気付けばログに・・・
Mar 29 18:08:02 hostname kernel: printk: 48843 messages suppressed. Mar 29 18:08:02 hostname kernel: TCP: time wait bucket table overflow Mar 29 18:08:07 hostname kernel: printk: 54962 messages suppressed. Mar 29 18:08:07 hostname kernel: TCP: time wait bucket table overflow Mar 29 18:08:12 hostname kernel: printk: 64843 messages suppressed. Mar 29 18:08:12 hostname kernel: TCP: time wait bucket table overflow
ワッショイヽ(゚∀゚)メ(゚∀゚)メ(゚∀゚)ノワッショイ
接続状況は・・・大量のTIME_WAITがっ
# netstat -tan | grep ':80 ' | awk '{print $6}' | sort | uniq -c 5 ESTABLISHED 11 FIN_WAIT1 1 FIN_WAIT2 1 LISTEN 3 SYN_RECV 149324 TIME_WAIT
ワッショイヽ(゚∀゚)メ(゚∀゚)メ(゚∀゚)ノワッショイ
お待ちになられております・・・
# netstat -ton tcp 0 0 ::ffff:172.xx.xx.xx:80 ::ffff:xx.xx.xx.aa:54648 TIME_WAIT timewait (27.05/0/0) tcp 0 0 ::ffff:172.xx.xx.xx:80 ::ffff:xx.xx.xx.bb:54720 TIME_WAIT timewait (7.67/0/0) tcp 0 0 ::ffff:172.xx.xx.xx:80 ::ffff:xx.xx.xx.cc:55908 TIME_WAIT timewait (52.52/0/0) tcp 0 0 ::ffff:172.xx.xx.xx:80 ::ffff:xx.xx.xx.dd:55918 TIME_WAIT timewait (44.23/0/0) tcp 0 0 ::ffff:172.xx.xx.xx:80 ::ffff:xx.xx.xx.ee:55906 TIME_WAIT timewait (30.47/0/0) tcp 0 0 ::ffff:172.xx.xx.xx:80 ::ffff:xx.xx.xx.ff:55842 TIME_WAIT timewait (24.80/0/0) tcp 0 0 ::ffff:172.xx.xx.xx:80 ::ffff:xx.xx.xx.gg:55910 TIME_WAIT timewait (15.51/0/0) tcp 0 0 ::ffff:172.xx.xx.xx:80 ::ffff:xx.xx.xx.hh:56164 TIME_WAIT timewait (53.01/0/0) tcp 0 0 ::ffff:172.xx.xx.xx:80 ::ffff:xx.xx.xx.ii:56162 TIME_WAIT timewait (30.65/0/0) tcp 0 0 ::ffff:172.xx.xx.xx:80 ::ffff:xx.xx.xx.jj:56166 TIME_WAIT timewait (15.65/0/0) ・・・・・以下10万行余り省略w・・・・・
アワワ ヽ(´Д`;≡;´Д`)丿 アワワ
net.ipv4.tcp_max_tw_buckets
tcp_max_tw_buckets (integer; default: 下記参照; Linux 2.4 以降)
Man page of TCP
システムが許容する TIME_WAIT 状態にあるソケットの最大数。この制限が存在するのは、単純な使用不能 (denial-of-service) 攻撃を防ぐために過ぎない。デフォルト値は NR_FILE*2 で、システムのメモリに応じて調整される。この数値を越えると、そのようなソケットはクローズされ、警告が表示される。
"tcp_max_tw_buckets"の値を、ちょっとずつ増やしてみたけど・・・変わらない!
ヾノ・∀・`)ムリムリ ヾノ'д'o)?? ム───(乂Д´)───リ!!
net.ipv4.tcp_tw_reuse
tcp_tw_reuse (Boolean; default: disabled; Linux 2.4.19/2.6 以降)
Man page of TCP
プロトコルの面から見て問題ない場合に新規コネクションに TIME_WAIT 状態のソケットを再利用することを許可する。技術的に詳しい人の助言や要請なしにこのオプションを変更すべきではない。
有効にしてみた。
# netstat -tan | grep ':80 ' | awk '{print $6}' | sort | uniq -c 2 ESTABLISHED 12 FIN_WAIT1 2 FIN_WAIT2 1 LISTEN 3 SYN_RECV 153076 TIME_WAIT
アワワ ヽ(´Д`;≡;´Д`)丿 アワワ
net.ipv4.tcp_tw_recycle
tcp_tw_recycle (Boolean; default: disabled; Linux 2.4 以降)
Man page of TCP
TIME_WAIT ソケットの素早い再利用を有効にする。このオプションを有効にすると、 NAT (ネットワークアドレス変換) を用いていると問題が生じるので、あまり推奨しない。
今回はバックエンド(internal)の話で、クライアント〜サーバ間で、NATを挟んでいるところは無かったので有効にしてみた。
# netstat -tan | grep ':80 ' | awk '{print $6}' | sort | uniq -c 9 ESTABLISHED 14 FIN_WAIT1 1 FIN_WAIT2 1 LISTEN 5 SYN_RECV 22 TIME_WAIT
( ̄ー+ ̄). ( ̄∇+ ̄)vキラーン
おわりに
本当は、TIME_WAIT自体のタイムアウトを60sから短くしたかったが、kernelのrebuildがし辛い状況で...あと、
実は、HTTP接続なので、きちんとKeep-Aliveを使える状態にすべし。(まとまってない)
=͟͟͞͞(๑•̀=͟͟͞͞(๑•̀д•́=͟͟͞͞(๑•̀д•́๑)=͟͟͞͞(๑•̀д•́
おまけ
説明
TCPソケットのTIME_WAIT状態を管理するために使用するスラブキャッシュのサイズが最大値(tcp_max_tw_buckets)に達した。
tcp_max_buckets はユーザーが設定することができ、デフォルト値は 16384 である。
現在の値を確認するには、以下の2つの方法のいずれかを利用すればよい。
1. # cat /proc/sys/net/ipv4/tcp_max_tw_buckets 2. # sysctl net.ipv4.tcp_max_tw_bucketshttp://ossmpedia.org/messages/linux/2.6.9-34.EL/29972.ja対処
tcp_max_tw_buckets をシステムの TCP ソケット利用状況に合わせて拡張する。
この制限は、DOS攻撃に対処するためだけに設けられているもので、この値を大きくすることで、メモリリソースなどを無闇に消費することはない。
tcp_max_tw_buckets の設定方法は以下の2つがある。
1. # echo <スラブキャッシュサイズ> > /proc/sys/net/ipv4/tcp_max_tw_buckets 2. # sysctl -w net.ipv4.tcp_max_tw_buckets=<スラブキャッシュサイズ>
参考
- Man page of TCP
- http://www.redbooks.ibm.com/redpapers/pdfs/redp3861.pdf
- Tuning Red Hat Enterprise Linux on IBM Eserver xSeries Servers
- どさにっき
- いっぱい接続したいの - (ひ)メモ
- TCP/IP通信の状態を調べる「netstat」コマンドを使いこなす (1/2):Tech TIPS - @IT
- 作者: W.リチャードスティーヴンス,W.Richard Stevens,橘康雄,井上尚司
- 出版社/メーカー: ピアソンエデュケーション
- 発売日: 2000/12
- メディア: 単行本
- 購入: 6人 クリック: 81回
- この商品を含むブログ (41件) を見る