私はnginxリバースプロキシのwrk
を使用していくつかの負荷テストを行っています->私のウェブアプリのセットアップで、1000以上の同時接続に到達すると、nginxが502と次のエラーメッセージを返し始めます。
2015/04/17 20:45:26 [crit] 6068#0: *1116212677 connect() to \
127.0.0.1:3004 failed (99: Cannot assign requested address) \
while connecting to upstream, client: xxx.xxx.xx.165, server: \
foo.bar.com, request: "GET /my/route HTTP/1.1", upstream: \
"http://127.0.0.1:3004/my/route", Host: "foo.bar.com"
wrk
コマンドは:
wrk -t10 -c500 -d5m "https://foo.bar.com/my/route" -H "Accept: application/json"
私はここで何が間違っているのかを理解しようとしています。 Webアプリケーションは、ポート3004でnginxによってプロキシされたリクエストをリッスンしています。nginxでポートが不足していますか? Webアプリケーションはこれだけのリクエストを処理できませんか?リクエストはタイムアウトしていますか?これについてははっきりしていません。もっと詳しく知りたいと思います。
このメッセージは、ローカルのソケット/ポートが不足していることを示しています。
ネットワークの制限を増やしてみてください。
echo "10240 65535" > /proc/sys/net/ipv4/ip_local_port_range
sysctl net.ipv4.tcp_timestamps=1
sysctl net.ipv4.tcp_tw_recycle=0
sysctl net.ipv4.tcp_tw_reuse=1
sysctl net.ipv4.tcp_max_tw_buckets=10000
あるいは、UNIXソケットを試して、それが役立つかどうかを確認することもできます。
ネットワークソケットの概要TCPを介して接続が確立されると、ローカルホストとリモートホストの両方にソケットが作成されます。リモートIPアドレスとポートは接続のサーバー側に属しており、接続を開始する前にクライアントが決定する必要があります。ほとんどの場合、クライアントは接続に使用するローカルIPアドレスを自動的に選択しますが、接続を確立するソフトウェアによって選択されることもあります。最後に、ローカルポートは、オペレーティングシステムによって使用可能にされた定義済みの範囲からランダムに選択されます。ポートは、接続の間だけクライアントに関連付けられるため、エフェメラルと呼ばれます。接続が終了すると、一時ポートが再利用可能になります。
ソリューションキープアライブ接続を有効にする
Keepaliveディレクティブを使用して、NGINXから上流サーバーへのキープアライブ接続を有効にし、各ワーカープロセスのキャッシュに保持される上流サーバーへのアイドルキープアライブ接続の最大数を定義します。この数を超えると、最も使用頻度の低い接続が閉じられます。キープアライブがないと、オーバーヘッドが増え、接続と一時ポートの両方で非効率になります。
http {
upstream backend {
server 10.0.0.100:1234;
server 10.0.0.101:1234;
}
server {
# ...
location / {
# ...
proxy_pass http://backend;
proxy_bind $split_ip;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
split_clients "$remote_addr$remote_port" $split_ip {
10% 10.0.0.210;
10% 10.0.0.211;
10% 10.0.0.212;
10% 10.0.0.213;
10% 10.0.0.214;
10% 10.0.0.215;
10% 10.0.0.216;
10% 10.0.0.217;
10% 10.0.0.218;
* 10.0.0.219;
}
}
詳細: https://www.nginx.com/blog/overcoming-ephemeral-port-exhaustion-nginx-plus/