課題
nginxでsocket(pathname)を使用して通信効率をあげようとしてみた。通信量が増えてきた所でResource temporarily unavailable
ということでリソース不足で怒られるようになった。
2015/11/10 23:02:27 [error] 1298#0: *296601104 connect() to unix:///tmp/sample.sock failed (11: Resource temporarily unavailable) while connecting to upstream, client: 192.168.1.2, server: hoge.com, request: "POST /sample.php?p=xx_xx&_=1447164211618 HTTP/1.1", upstream: "uwsgi://unix:///tmp/sample.sock:", host: "hoge.com", referrer: "https://www.foo.com/xxx/yyy/"
設定
対象になりそうな部分だけみてみると、
worker_processes 2;
worker_rlimit_nofile 65536;
events {
worker_connections 1024;
}
location / {
# uWSGI application
include uwsgi_params;
uwsgi_pass unix:///tmp/sample.sock;
uwsgi_connect_timeout 2s;
uwsgi_read_timeout 2s;
}
思い当たりそうなところを調べてみる
ulimitか?
# ulimit -n
1024
多くは無いけどw
socket fileは大量に出来るわけでも無いのでなんか違う気がする。
ファイルディスクリプタが問題ならtoo many open filesのほうが出てきそう。
Apacheの時は256
くらいのプロセス数でやったことを考えると、Nginxなら2048
くらいのコネクションが精一杯か...サーバ増やすのも対して面倒じゃなくなったのでスケールアウトなんてことも
そんなわきゃない
ネットワーク状態遷移とNginxへ通信が到達するところまでを調べてみた。
kernelのところに影響があったのか!
見てみる
# sysctl net.core.somaxconn
net.core.somaxconn = 128
128??? すくなっ!?
nginxで2048
を受けること考えると倍くらいでも良いのかもしれないけど、大きめに設定。この値はnet.core.somaxconnより大きかった場合、net.core.somaxconnの値を優先するようです。
(環境に合わせて数値は変更してください)
--(snip)--
net.ipv4.tcp_max_syn_backlog = 20480
net.core.somaxconn=20480
# sysctl -p
様子を見る
ログが出ないことを確認するでも良いのだがkernelのところの数値なのでもう少し深掘りしてみたい。
net.core.somaxconn=2048
のとき: 赤枠の所で少しあふれた
net.core.somaxconn=20480
のとき
embryonic resets?
Configuring TCP InterceptやTCP half-openによると
一般的には、TCP SYN、SYN ACKまでのやり取りがされた、完全ではないTCPコネクションをハーフオープンセッションと呼んだりします。他にも呼び方はいろいろあります(embryonicとも言ったりします)が、ハーフオープンセッションと言えば大体通じると思います。
なるほど、ハーフオープンセッションがリセットされた(dropのような)ことが起きてると解釈できそうな気がするので、この数値が下がってると少なくとも改善していそう!!
そういえば
Resource temporarily unavailable
ってなんだろうと
stack traceのコマンドで見れるらしい。
strace -tt -p [TARGET_PID] 2>&1 |tee /tmp/trace.txt|grep EAGAIN
00:51:18.848228 read(71, 0x2344873, 33093) = -1 EAGAIN (Resource temporarily unavailable)
00:51:18.855058 read(36, 0x2344873, 33093) = -1 EAGAIN (Resource temporarily unavailable)
00:51:18.858554 write(682, "hogehog""..., 5679) = -1 EAGAIN (Resource temporarily unavailable)
00:51:18.892731 recvfrom(71, 0x2395418, 109, 0, 0, 0) = -1 EAGAIN (Resource temporarily unavailable)
00:51:18.902643 recvfrom(383, 0x3425370, 213, 0, 0, 0) = -1 EAGAIN (Resource temporarily unavailable)
00:51:18.909802 recvfrom(383, 0x7fff72d0a7bf, 1, 2, 0, 0) = -1 EAGAIN (Resource temporarily unavailable)
00:51:18.916927 recvfrom(383, 0x3c2e640, 1024, 0, 0, 0) = -1 EAGAIN (Resource temporarily unavailable)
00:51:18.923724 read(406, 0x2344873, 33093) = -1 EAGAIN (Resource temporarily unavailable)
いっぱい出てきたのでこの辺にしておこう。。。
まとめ
相変わらずSocketまわりを調べると知らないことがたくさんある... EAGAIN
がなんぞやなんて疑問が出てきてしまいまだまだ調べることは多そう
参考資料
Tuning TCP and NGINX on EC2
http://www.slideshare.net/chartbeat/tuning-tcp-and-nginx-on-ec2Tuning NGINX for Performance
https://www.nginx.com/blog/tuning-nginx/