タイトルは釣りでnginxにかぎらずリバースプロキシ使うならって話。
高負荷サイトのフロントにnginxをリバースプロキシとしてたてて後ろのサーバーへリクエストをなげていたら数百rpsでいろいろなエラーがnginxのログに落ちてきた。 その時にとった対策を少しまとめてみる。
まず、nginxのエラーログに下のようなエラーの対処法。
nginx: [emerg] bind() to 127.0.0.1:8080 failed (99: Cannot assign requested address)
$ netstat -an |grep TIME_WAIT |wc
このときのwcの結果は2万数千あり、詳細を調べていくとその中の大部分が後ろのサーバーからnginxにリクエストを返すために利用したポートがほとんどであった。
これを解消するための対策として一番手っ取り早いのがカーネルのチューニングである。
$ sysctl net.ipv4.ip_local_port_range net.ipv4.ip_local_port_range 32768 61000 $ sudo sysctl -w net.ipv4.ip_local_port_range="10240 61000" $ sysctl net.ipv4.ip_local_port_range net.ipv4.ip_local_port_range 10240 61000
上限は変更しないで下限だけ変更して利用できるエフェメラルポートを増やすようにした。
これでもダメな場合に nginxと後ろのアプリケーションサーバーの間をKeepAliveして接続数を抑える。 これが本当に効果的でアプリケーションサーバーからnginxへのレスポンスを返すコネクションがKeepAliveの本数だけに減るのでトータルのエフェメラルポートが万単位から100前後にまで劇的に減らせた。
さらに、コネクションが減ったことでメモリ使用量も20%前後改善したのでメモリが足りないサーバーでもこの設定は効果的だと思った。
Too many open filesが出た時
accept() failed (24: Too many open files) while accepting new connection on 127.0.0.1:80
さらに高負荷になったときにnginxのログにToo many 〜のエラーが落ちるようになった。
% cat /proc/12345/limits |grep "Max open files" Max open files 4096 4096 files # ulimitを使ってopen出来るファイル数の上限を増やす % sudo sh -c "ulimit -n 32768" # nginx を再起動 % cat /proc/12345/limits |grep "Max open files" Max open files 32768 32768 files
nginx で Too many open files エラーに対処する - Shin x blog
apacheでも同じようなことが起きると思うのでよくやる設定だとおもう。 サーバーが再起動するとこの設定が無効になるので再起動した際はちゃんと設定が有効か確認しましょう。
2014-05-14 追記
worker_rlimit_nofile で増やすほうがスマートってことを教えてもらったのでこれを設定するようにした。 設定する値は worker_connections の3〜4倍くらいが良いらしいが自分はとりあえず2倍に設定をした。 nginx で Too many open files エラーに対処する - Shin x blog