サーバーをプログラミングしていますが、接続数を「無制限」に設定しても帯域幅が飽和しないため、接続数が制限されているようです。
Ubuntu Linuxボックスが一度に開くことができる接続の最大数を増加または排除するにはどうすればよいですか?OSはこれを制限しますか、それともルーターまたはISPですか?それとも別のものですか?
サーバーをプログラミングしていますが、接続数を「無制限」に設定しても帯域幅が飽和しないため、接続数が制限されているようです。
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
1秒あたりのソケット数以上を一貫して保証できないことを意味します。これに満足できない場合は、を増やすことから始めることができます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秒あたりの発信接続を行うためのシステム機能に影響を与える要素として解釈されるべきではありません。しかし、むしろこれらの要因は、長期間の「アクティビティ」の間、持続的な方法で同時接続を処理するシステムの能力に影響を与えます。
以下のための一般的なLinuxボックス上のsysctl値をデフォルトtcp_tw_recycle
&tcp_tw_reuse
だろう
net.ipv4.tcp_tw_recycle=0
net.ipv4.tcp_tw_reuse=0
これらは、「使用された」ソケット(待機状態)からの接続を許可せず、ソケットに強制的に完全な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デバイスの背後にある2台の異なるコンピューターからの接続を処理しないため、一般に公開されているサーバーにとっては非常に問題です。Linux 4.12から削除net.ipv4.tcp_tw_recycle
されたことに注意してください。
サーバー側では:net.core.somaxconn
値が重要な役割を担っています。待機ソケットにキューイングされるリクエストの最大数を制限します。サーバーアプリケーションの機能が確実である場合は、デフォルトの128から128から1024などに引き上げます。これで、アプリケーションのリッスンコールのリッスンバックログ変数を同等以上の整数に変更することで、この増加を利用できます。
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の要素を増やして、クライアント側とサーバー側の両方のアプリケーションを起動することを忘れないでください。
上記に加えて、プログラマが使用するもう1つの一般的な手法は、tcp書き込み呼び出しの数を減らすことです。私の好みは、クライアントに送信するデータをプッシュするバッファーを使用し、適切な時点で、バッファーされたデータを実際のソケットに書き込むことです。この手法により、大きなデータパケットを使用し、断片化を減らし、ユーザーランドとカーネルレベルの両方でCPU使用率を減らすことができます。
(61000 - 32768) / 60 = 470 sockets per second
。これについて詳しく説明していただけますか?
接続の最大数を設定するいくつかの変数があります。ほとんどの場合、最初にファイル番号が不足しています。ulimit -nを確認してください。その後、/ procに設定がありますが、デフォルトでは数万に設定されています。
さらに重要なことに、何か間違ったことをしているようです。1つのTCP接続で、2つのパーティ間のすべての帯域幅を使用できる必要があります。そうでない場合:
ping -s 1472
...)tc
iperf
誤解しているのかもしれません。たぶん、あなたはたくさんの接続が必要なビットトレントのようなことをしているでしょう。その場合は、実際に使用している接続の数を確認する必要があります(netstat
またはを試してくださいlsof
)。その数が多い場合は、次のことが考えられます。
ulimit -n
。それでも、1000接続(私のシステムのデフォルト)はかなりの数です。iostat -x
か?また、コンシューマーグレードのNATルーター(Linksys、Netgear、DLinkなど)を使用している場合は、何千もの接続でその能力を超える可能性があることに注意してください。
これが何らかの助けとなることを願っています。あなたは本当にネットワーキングの質問をしています。
デロバートの答えを改善するために、
nf_conntrack_maxをキャッチすることで、OSの接続制限を確認できます。
例: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}'
which awk
awkへのパスを決定するあなたの友達です
which
、プログラムに依存しています。(とはいえ、スクリプト内のソリューションが完全に近いかどうかはわかりませんが、これがスクリプトの目的ではありません)。PATH
awk
awk
場所を決定するかが気に入っていますが、シェルは常にあると想定しています/bin/bash
(プロヒント:デフォルトでは、AIX5 / 6にはbashさえありません)。
awk
検出が便利?個人的に私は単純に正しいを持つことが前提となりPATH
ますが、合理的な選択肢が考えられ/usr/bin/env awk
そして/usr/bin/env bash
それぞれ。それが価値があるのは、私のLinuxシステムの場所が間違っていることです。それは/usr/bin/awk
ない/bin/awk
アプリケーションレベルで、開発者ができることは次のとおりです。
サーバー側から:
ロードバランサー(ある場合)が正しく動作するかどうかを確認します。
遅い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
クライアント側でもいくつかの作業を行うことができます。
呼び出しをバッチでグループ化し、トラフィックとリクエストの総数をクライアントとサーバーの数で減らします。
不要な重複リクエストを処理するために、キャッシュの中間層を構築してみてください。