え、サーバ増やしてませんか？ソケット設定したその後に！？


#課題

nginxでsocket(pathname)を使用して[通信効率をあげよう](http://qiita.com/kuni-nakaji/items/d11219e4ad7c74ece748)としてみた。通信量が増えてきた所で`Resource temporarily unavailable`ということでリソース不足で怒られるようになった。

```error_log
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/"
```

#設定

対象になりそうな部分だけみてみると、

```nginx.conf
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;
  }
```

#思い当たりそうなところを調べてみる

うーん、リソース不足...CPUもメモリもまだ余裕がある
![memory-pinpoint_1446718435_1447270531.png](https://qiita-image-store.s3.amazonaws.com/0/8726/53b20582-8717-d857-edc2-9e738ff7d165.png "memory-pinpoint_1446718435_1447270531.png") ![cpu-pinpoint_1446722754_1447199682.png](https://qiita-image-store.s3.amazonaws.com/0/8726/2e0dbbc8-b147-87b8-67a4-cd2b832ec9d7.png "cpu-pinpoint_1446722754_1447199682.png")

ulimitか？

```
# ulimit -n
1024
```

多くは無いけどｗ

socket fileは大量に出来るわけでも無いのでなんか違う気がする。
ファイルディスクリプタが問題なら[too many open files](http://d.hatena.ne.jp/akishin999/20130213/1360711554)のほうが出てきそう。

Apacheの時は`256`くらいのプロセス数でやったことを考えると、Nginxなら`2048`くらいのコネクションが精一杯か...サーバ増やすのも対して面倒じゃなくなったのでスケールアウトなんてことも

# そんなわきゃない

[ネットワーク状態遷移](http://qiita.com/kuni-nakaji/items/c07004c7d9e5bb683bc2)とNginxへ通信が到達するところまでを調べてみた。

![socket.png](https://qiita-image-store.s3.amazonaws.com/0/8726/98e43893-e05b-090a-2be9-fb2cf8e98032.png "socket.png")

kernelのところに影響があったのか！

見てみる

```
# sysctl net.core.somaxconn
net.core.somaxconn = 128
```

**128???** すくなっ!?

nginxで`2048`を受けること考えると倍くらいでも良いのかもしれないけど、大きめに設定。この値はnet.core.somaxconnより大きかった場合、net.core.somaxconnの値を優先するようです。
**(環境に合わせて数値は変更してください)**


```/etc/sysctl.conf
--(snip)--
net.ipv4.tcp_max_syn_backlog = 20480
net.core.somaxconn=20480
```


```cmd
# sysctl -p
```

#様子を見る

ログが出ないことを確認するでも良いのだがkernelのところの数値なのでもう少し深掘りしてみたい。

`net.core.somaxconn=2048` のとき: 赤枠の所で少しあふれた

![B_SOCKBUFERR-day.png](https://qiita-image-store.s3.amazonaws.com/0/8726/4dbc971d-4756-e4ce-a79c-b77eb0ac58c1.png "B_SOCKBUFERR-day.png")

`net.core.somaxconn=20480` のとき

![A_SOCKBUFERR-day.png](https://qiita-image-store.s3.amazonaws.com/0/8726/1dde3666-defa-9006-398c-41e8e654e357.png "A_SOCKBUFERR-day.png")

#embryonic resets?

[Configuring TCP Intercept](http://www.n-study.com/network/2006/07/configuring_tcp_intercept1.html)や[TCP half-open](https://en.wikipedia.org/wiki/TCP_half-open)によると

```
一般的には、TCP SYN、SYN ACKまでのやり取りがされた、完全ではないTCPコネクションをハーフオープンセッションと呼んだりします。他にも呼び方はいろいろあります（embryonicとも言ったりします）が、ハーフオープンセッションと言えば大体通じると思います。
```

なるほど、ハーフオープンセッションがリセットされた(dropのような)ことが起きてると解釈できそうな気がするので、この数値が下がってると少なくとも改善していそう！！

#そういえば

`Resource temporarily unavailable`ってなんだろうと

stack traceのコマンドで見れるらしい。

```cmd
strace -tt -p [TARGET_PID] 2>&1 |tee /tmp/trace.txt|grep EAGAIN
```

```log
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-ec2


> Tuning NGINX for Performance
> https://www.nginx.com/blog/tuning-nginx/