ピクセルトラッキングを想定した設定で、Nginx on EC2(c3.large) という環境で、極限まで設定をして、どれぐらいさばけるのか運用中、パフォーマンステストしてる時は、別のところに問題があり、Nginx自体の性能限界までテストできなかったので、実際どこまでいけるのかは計測できてない。
秒間1万とか2万は行けてたと思う、ちなみに実際の運用では秒間9000以上とかを記録していて、サーバ自体にはかなり余裕があるので、記録はまだまだ伸びると思う。
ちなみに empty_gif は応答が短すぎて、Nginx の $request_time では記録できない... 全部 "0.000" だから、どれぐらい掛かってるのか分からん...。
nginx.confの設定
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
worker_rlimit_nofile 150000;
events {
worker_connections 65535;
multi_accept on;
use epoll;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" "$request_time"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
keepalive_timeout 120;
server_tokens off;
gzip off;
server {
listen 80;
server_name example.jp;
error_log /var/log/nginx/example.jp.error.log;
root /var/www/;
location / {
access_log /var/log/nginx/example.jp.access.log main;
empty_gif;
}
}
}
worker_connections
最大同時接続数は使用できるポート数以上設定しても意味ないので、上限の 65535 を設定
worker_rlimit_nofile
ファイルディスクリプタ上限数は、通常1つの接続につきエフェメラルポート用のソケットファイルと実際に返答するコンテンツファイルだとお思うので、worker_connections に対して2倍以上を設定しておけば良いと思うのですが、ふと HTTP Pipelining が利用された場合はこの比じゃない気がしたんだが、どうなんだろう...。
multi_accept
リクエストを同時に受け付けられるならその方が良いと思う...
use epoll
あれ、これって別に指定しなくても自動で選択されるよね??とりあえず、明示しておいた方が安心なので...
sendfile
empty_gif なので意味はない気がする...
tcp_nopush
なるべく少ないパケットで通信をした方が効率が良いように思うので...
keepalive_timeout
ELB配下のEC2環境なので、AWS推奨の120秒以上に設定
TCP カーネルパラメータ
sysctl -w net.ipv4.ip_local_port_range="18000 65535"
sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w net.ipv4.ip_dynaddr=1
sysctl -w net.ipv4.tcp_rfc1337=1
sysctl -w net.ipv4.tcp_fin_timeout=10
sysctl -w net.ipv4.tcp_keepalive_probes=5
sysctl -w net.ipv4.tcp_slow_start_after_idle=0
sysctl -w net.ipv4.tcp_max_syn_backlog=1024
sysctl -w net.core.somaxconn=65535
上記以外の設定に関しては、副作用の問題が報告されてたりして、ちょっと危険そうなのでやってないのと、そもそも、ここまでやっておけば、他のところがボトルネックになる可能性の方が高いと思うの、ひとまずここまでってのもある。
net.ipv4.ip_local_port_range
これを増やさないことには同時接続数を増やしても...。可能なら 1024-65535 とかの方が良いと思う
※iptablesやAWSだとNetworkACLとかで同様に必要に応じて開放しておかないとパケットが途中で止まってハマる
net.ipv4.tcp_tw_reuse
再利用した方が速いと思うよ...
net.ipv4.ip_dynaddr
DHCP環境なので設定しておいた方が良いかなと
net.ipv4.tcp_rfc1337
RFC1337に準拠させる。TIME_WAIT状態のときにRSTを受信した場合、TIME_WAIT期間の終了を待たずにそのソケットをクローズする
TIME_WAITは何かと問題になるし、待たなくて済むならその方が良いと思うので
net.ipv4.tcp_fin_timeout
タイムアウトはなるべく短い方がいいと思うので
net.ipv4.tcp_keepalive_probes
TCP が keepalive プローブを送る数。この数に達すると、 その接続が壊れたとみなします。デフォルトの値は 9 です。 この値に tcp_keepalive_intvl をかけると、 ある keepalive が送られた後に許される無反応時間が得られます。
あんまり待って欲しくないし、さっさと次へ行ってほしいので
net.ipv4.tcp_slow_start_after_idle
アイドルとかしなくて良いんじゃないか?
net.ipv4.tcp_max_syn_backlog
EC2だと128で少ないため増やしておく
net.core.somaxconn
上記同様EC2だと128しかないので最大値である65535まで引き上げておく
IRQ
TODO: smp_affinity
http://tsuchinoko.dmmlabs.com/?p=627
https://access.redhat.com/documentation/ja-JP/Red_Hat_Enterprise_Linux/6/html/Performance_Tuning_Guide/s-cpu-irq.html
RPS/RFS
Nginx参考:
http://nodejs.osser.jp/server/nginx-max-performance/
http://dak1n1.com/blog/12-nginx-performance-tuning
http://www.mk-mode.com/octopress/2014/04/13/nginx-file-discriptor-limit/
http://shinobra.com/2012/02/sawanoboly/smartos_nginx_too-many-open-files
TCP参考:
http://qiita.com/kuni-nakaji/items/c07004c7d9e5bb683bc2
http://linux.mini13i.com/?kernel%2F%A5%B7%A5%B9%A5%C6%A5%E0%A5%D1%A5%E9%A5%E1%A5%BF
http://linuxjf.sourceforge.jp/JFdocs/Adv-Routing-HOWTO/lartc.kernel.obscure.html
http://www.nateware.com/linux-network-tuning-for-2013.html