サーバーをプログラミングしていますが、接続数を「無制限」に設定しても帯域幅が飽和していないため、接続数が制限されているようです。
Ubuntu Linuxボックスが一度に開くことができる最大接続数を増減するにはどうすればよいですか? OSはこれを制限していますか?それともルーターですか?それともISPですか?それとも他の何か?
最大接続数は、クライアント側とサーバー側の両方での一定の制限の影響を受けますが、多少異なります。
クライアント側:サーマルポートの範囲を広げ、tcp_fin_timeout
を減らします。
デフォルト値を調べるには
sysctl net.ipv4.ip_local_port_range
sysctl net.ipv4.tcp_fin_timeout
サーマルポート範囲は、ホストが特定のIPから作成できるアウトバウンドソケットの最大数を定義します。住所。 fin_timeout
は、これらのソケットがTIME_WAIT
状態を維持する最小時間を定義します(一度使用されると使用できなくなります)。通常のシステムデフォルトは次のとおりです。
net.ipv4.ip_local_port_range = 32768 61000
net.ipv4.tcp_fin_timeout = 60
これは基本的にあなたのシステムが毎秒(61000 - 32768) / 60 = 470
個以上のソケットを一貫して保証できないことを意味します。あなたがそれに満足していないのなら、あなたはport_range
を増やすことから始めることができます。最近では、範囲を15000 61000
に設定することはかなり一般的です。 fin_timeout
を減らすことで可用性をさらに高めることができます。両方ともしたとすると、1秒あたり1500以上のアウトバウンド接続が見やすくなるはずです。
値を変更する:
sysctl net.ipv4.ip_local_port_range="15000 61000"
sysctl net.ipv4.tcp_fin_timeout=30
上記は、1秒あたりのアウトバウンド接続を確立するためのシステム機能に影響を与える要因として解釈されるべきではありません。しかし、むしろこれらの要因は、長期間の「活動」に対して持続可能な方法で同時接続を処理するシステムの能力に影響を与えます。
tcp_tw_recycle
およびtcp_tw_reuse
の一般的なLinuxボックスのデフォルトのSysctl値は次のようになります。
net.ipv4.tcp_tw_recycle=0
net.ipv4.tcp_tw_reuse=0
これらは "待機"状態の "used"ソケットからの接続を許可せず、ソケットにtime_wait
サイクル全体を強制的に継続させます。設定をお勧めします。
sysctl net.ipv4.tcp_tw_recycle=1
sysctl net.ipv4.tcp_tw_reuse=1
これはtime_wait
状態のソケットの高速循環とそれらの再利用を可能にします。しかし、この変更を行う前に、これが、これらのソケットを必要とするアプリケーションに使用するプロトコルと競合しないことを確認してください。意味を理解するために、ポスト "Vincent BernatからのTCP TIME-WAITへの対処" を必ず読んでください。 net.ipv4.tcp_tw_recycle
オプションは、同じNAT deviceの背後にある2台の異なるコンピュータからの接続を処理しないため、一般向けのサーバーでは非常に問題があります。噛むnet.ipv4.tcp_tw_recycle
はLinux4.12から 削除 されています。
サーバー側:net.core.somaxconn
値は重要な役割を果たします。待機ソケットに対してキューに入れられる要求の最大数を制限します。サーバーアプリケーションの機能が確実な場合は、デフォルトの128から128から1024のような値に増やしてください。これで、アプリケーションのlisten呼び出しのlisten backlog変数を同等またはそれ以上の整数に変更することで、この増加を利用できます。
sysctl net.core.somaxconn=1024
あなたのイーサネットカードのtxqueuelen
パラメータも果たすべき役割を持っています。デフォルト値は1000なので、あなたのシステムがそれを処理することができるならば、5000またはそれ以上にそれらを上げます。
ifconfig eth0 txqueuelen 5000
echo "/sbin/ifconfig eth0 txqueuelen 5000" >> /etc/rc.local
同様に、net.core.netdev_max_backlog
とnet.ipv4.tcp_max_syn_backlog
の値を増やします。デフォルト値はそれぞれ1000と1024です。
sysctl net.core.netdev_max_backlog=2000
sysctl net.ipv4.tcp_max_syn_backlog=2048
シェルでFD ulimtを増やして、クライアント側とサーバー側の両方のアプリケーションを起動することを忘れないでください。
プログラマーによって使用される上記の1つのよりポピュラーなテクニックに加えて、tcp write呼び出しの数を減らすことです。私自身の好みは、私がクライアントに送りたいデータをプッシュし、それから適切な時点でバッファリングされたデータを実際のソケットに書き出すバッファを使うことです。このテクニックを使用すると、大きなデータパケットを使用したり、断片化を減らしたり、ユーザーレベルでもカーネルレベルでもCPU使用率を減らしたりできます。
最大接続数を設定するための変数がいくつかあります。たぶん、あなたは最初にファイル番号を使い果たしています。 ulimit -nを確認してください。その後、/ procに設定がありますが、デフォルトでは何万にも設定されています。
さらに重要なのは、何か問題があるように思われることです。単一のTCP接続は、2者間のすべての帯域幅を使用できるはずです。そうでない場合:
ping -s 1472
...)tc
で構成されています。iperf
)。おそらく私は誤解しています。多分あなたはたくさんの接続が必要なBittorrentのようなことをしているのでしょう。そうであれば、実際に使用している接続数を把握する必要があります(netstat
またはlsof
を試してください)。その数が多い場合は、次のようにします。
ulimit -n
を上げる必要があるかもしれません。それでも、〜1000接続(私のシステムのデフォルト)はかなりの数です。iostat -x
をチェックしましたか?また、コンシューマグレードのNATルーター(Linksys、Netgear、DLinkなど)を使用している場合は、何千もの接続で能力を超える可能性があることに注意してください。
これが助けになることを願っています。あなたは本当にネットワーキングの質問をしています。
Derobertによって与えられた答えを改善するために、
あなたはあなたのOS接続制限がnf_conntrack_maxを捕獲することによって何であるか決定することができます。
たとえば、次のようになります。cat/proc/sys/net/netfilter/nf_conntrack_max
次のスクリプトを使用して、特定の範囲のTCPポートへのTCP接続数をカウントできます。デフォルトは1〜65535です。
これにより、OSの接続制限を超えていないかどうかを確認できます。
これがスクリプトです。
#!/bin/bash
OS=$(uname)
case "$OS" in
'SunOS')
AWK=/usr/bin/nawk
;;
'Linux')
AWK=/bin/awk
;;
'AIX')
AWK=/usr/bin/awk
;;
esac
netstat -an | $AWK -v start=1 -v end=65535 ' $NF ~ /TIME_WAIT|ESTABLISHED/ && $4 !~ /127\.0\.0\.1/ {
if ($1 ~ /\./)
{sip=$1}
else {sip=$4}
if ( sip ~ /:/ )
{d=2}
else {d=5}
split( sip, a, /:|\./ )
if ( a[d] >= start && a[d] <= end ) {
++connections;
}
}
END {print connections}'
アプリケーションレベルでは、開発者ができることは次のとおりです。
サーバー側から:
ロードバランサ(ある場合)が正常に動作しているかどうかを確認します。
ロードバランサが正しく動作する場合は、slow TCPタイムアウトを503 Fast Immediateレスポンスに変更します。
例:ノードサーバを使用している場合、uはnpmからtoobusyを使用できます。以下のような実装
var toobusy = require('toobusy');
app.use(function(req, res, next) {
if (toobusy()) res.send(503, "I'm busy right now, sorry.");
else next();
});
なぜ503?ここに過負荷のためのいくつかの良い洞察があります: http://ferd.ca/queues-don-t-fix-overload.html
クライアント側でもいくつかの作業を行うことができます。
呼び出しをまとめてグループ化し、トラフィックを減らし、クライアントとサーバーの要求数の合計を減らします。
不要な重複要求を処理するためにキャッシュ中間層を構築してみてください。