235

サーバーをプログラミングしていますが、接続数を「無制限」に設定しても帯域幅が飽和していないため、接続数が制限されているようです。

Ubuntu Linux ボックスが一度に開くことができる接続の最大数を増やしたり、削除したりするにはどうすればよいですか? OSがこれを制限していますか、それともルーターまたはISPですか?それとも別のものですか?

4

4 に答える 4

456

接続の最大数は、クライアント側とサーバー側の両方で特定の制限の影響を受けますが、少し異なります。

クライアント側: 一時ポートの範囲を増やし、ポート範囲を減らします。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 秒あたりのアウトバウンド接続を作成するシステム機能に影響を与える要因として解釈されるべきではありません。むしろ、これらの要因は、長時間の「アクティビティ」に対して持続可能な方法で同時接続を処理するシステムの能力に影響を与えます。

tcp_tw_recycle&の典型的な Linux ボックスのデフォルトの Sysctl 値は次の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 ulimts を増やして、クライアント側とサーバー側の両方のアプリケーションを開始することを忘れないでください。

上記のほかに、プログラマーが使用するもう 1 つの一般的な手法は、 tcp 書き込み呼び出しの数を減らすことです。私自身の好みは、クライアントに送信したいデータをプッシュするバッファを使用し、適切な時点でバッファリングされたデータを実際のソケットに書き出すことです。この手法により、大きなデータ パケットを使用し、断片化を減らし、ユーザー ランドとカーネル レベルの両方で CPU 使用率を減らすことができます。

于 2010-10-13T12:49:44.110 に答える
70

接続の最大数を設定する変数がいくつかあります。ほとんどの場合、最初にファイル番号が不足しています。確認してくださいulimit -n。その後、 に設定がありますが/proc、それらはデフォルトで数万に設定されています。

さらに重要なことに、何か間違ったことをしているように聞こえます。1 つの TCP 接続で、2 つのパーティ間のすべての帯域幅を使用できる必要があります。そうでない場合:

  • TCP ウィンドウの設定が十分に大きいかどうかを確認します。Linux のデフォルトは、非常に高速な inet リンク (数百 mbps) または高速なサテライト リンクを除いて、すべてに適しています。あなたの帯域幅*遅延積は何ですか?
  • 大きなパケットで ping を使用してパケット損失を確認します ( ping -s 1472...)
  • レート制限を確認します。Linux では、これは次のように構成されます。tc
  • たとえば、次のように使用して、存在すると思われる帯域幅が実際に存在することを確認します。iperf
  • プロトコルが正常であることを確認します。レイテンシーを覚えておいてください。
  • ギガビット+LANの場合、ジャンボパケットは使えますか? あなたは?

多分私は誤解しました。おそらく、Bittorrent のような、多くの接続が必要な作業を行っていると思います。その場合は、実際に使用している接続数を把握する必要があります (netstatまたはを試してくださいlsof)。その数がかなりの場合、次のことを行うことができます。

  • 100 mbps 以上の帯域幅を確保します。この場合、実際に をアップする必要があるかもしれませんulimit -n。それでも、約 1000 接続 (私のシステムのデフォルト) はかなりの数です。
  • 接続を遅くしているネットワークの問題がある (例: パケット損失)
  • 特に探している場合は、IO帯域幅など、他の何かを遅くしてください。チェックしましたiostat -xか?

また、コンシューマー グレードの NAT ルーター (Linksys、Netgear、DLink など) を使用している場合は、何千もの接続でその能力を超える可能性があることに注意してください。

これが何らかの助けになることを願っています。あなたは本当にネットワーキングの質問をしています。

于 2009-01-04T08:02:32.010 に答える
19

derobert の回答を改善するには、

nf_conntrack_max を cat することで、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}'
于 2012-10-12T18:36:35.707 に答える
10

アプリケーション レベルで、開発者ができることは次のとおりです。

サーバー側から:

  1. ロード バランサー (ある場合) が正しく動作するかどうかを確認します。

  2. 遅い TCP タイムアウトを 503 Fast Immediate 応答に変えます。ロード バランサーが正しく機能している場合、サービスを提供する作業リソースを選択する必要があり、予期しないエラー メッセージでハングアップするよりはましです。

例: ノード サーバーを使用している場合は、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

クライアント側でもいくつかの作業を行うことができます。

  1. 呼び出しをバッチでグループ化し、クライアントとサーバーのトラフィックと合計要求数を減らすようにしてください。

  2. 不要な重複リクエストを処理するためにキャッシュ中間層を構築してみてください。

于 2014-11-19T21:26:44.953 に答える