大量の接続がやってきた!ヤァ!ヤァ!ヤァ!

※ 以下、フィクションです。

はじめに: こんなサーバ(↓dstat)

(裏バッチによりiowaitとLAが高いのは一時的な仕様とする)

気付けばログに・・・

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 以降)
システムが許容する TIME_WAIT 状態にあるソケットの最大数。この制限が存在するのは、単純な使用不能 (denial-of-service) 攻撃を防ぐために過ぎない。デフォルト値は NR_FILE*2 で、システムのメモリに応じて調整される。この数値を越えると、そのようなソケットはクローズされ、警告が表示される。

Man page of TCP

"tcp_max_tw_buckets"の値を、ちょっとずつ増やしてみたけど・・・変わらない!
ヾノ・∀・`)ムリムリ ヾノ'д'o)?? ム───(乂Д´)───リ!!

net.ipv4.tcp_tw_reuse

tcp_tw_reuse (Boolean; default: disabled; Linux 2.4.19/2.6 以降)
プロトコルの面から見て問題ない場合に新規コネクションに TIME_WAIT 状態のソケットを再利用することを許可する。技術的に詳しい人の助言や要請なしにこのオプションを変更すべきではない。

Man page of TCP


有効にしてみた。

# 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 以降)
TIME_WAIT ソケットの素早い再利用を有効にする。このオプションを有効にすると、 NAT (ネットワークアドレス変換) を用いていると問題が生じるので、あまり推奨しない。

Man page of TCP


今回はバックエンド(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/IP〈Vol.1〉プロトコル

詳解TCP/IP〈Vol.1〉プロトコル

  • 作者: W.リチャードスティーヴンス,W.Richard Stevens,橘康雄,井上尚司
  • 出版社/メーカー: ピアソンエデュケーション
  • 発売日: 2000/12
  • メディア: 単行本
  • 購入: 6人 クリック: 81回
  • この商品を含むブログ (41件) を見る