localport枯渇・・・
忘れないうちにもう1つ。
最近のサーバはスペックがとてもよろしいので、ついつい待機FCGIの数を増やしたくなってしまうのですが、これでハマるところを直近2回ほど見たのでメモ。
FCGIを増やしたのに全然さばけなくてなんかこんなエラー出るし!みたいなときは
Can't connect to MySQL server on 'hostname' (99)
接続先のMySQLに対するlocalportが枯渇してた、なんてことがあります。
netstat -na | grep tcp | wc -l
これが3万近かったら以下を打ってみましょう。
> cat /proc/sys/net/ipv4/ip_local_port_range 32768 61000
こうなってたらlocalport枯渇してるのかもしれません。
どんくらいの数字を入れるのがいいかは人それぞれあるみたいですが、そのときは
> echo "2048 64512" > /proc/sys/net/ipv4/ip_local_port_range
なんてして6万強確保しました。
相手先のIP:PORTに対する数なので、DBが相手だったらslave増やしてあげるとか、masterだったらさっさとdisconnectするとか、webをKVMにしてリソースを分散してFCGIの数を抑えてあげるとかしないといけないんですね。
※追記
どうやらこれだけじゃTIME_WAIT残っちゃって焼け石に水なこともあり、不特定多数のクライアントからの接続を受ける環境では難あり。
ちなみにlocalport問題に対しては、こんなこと↓をするって記事も見かけますが、
> echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle > echo 10 > /proc/sys/net/ipv4/tcp_fin_timeout
これだと↓の記事にあるようにタイムスタンプつけたパケットがドロップされてしまうこともあるようで、外部接続を受けるwebサービスなんかでは余計な障害を引き起こしてしまうやも。。。
じゃーどうすんねん!!!
ってことでお隣の部署では
Linux kernelのTCP_TIMEWAIT_LENをチューニング
しているとのこと。
ざっくり↓の記事のようにkernelをリビルドしてあげちゃうのが効果てきめんだそうです。
TIME_WAITのチューニングとkernelリビルド for CentOS 6.0 - 逆襲のWebエンジニア
突き詰めるとkernelハックまで行っちゃうんですね。
TCP接続奥ふけぇぇぇぇぇ( ゚д゚)
- TCPの状態遷移をど忘れしたら見る。