問題タブ [nagle]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c# - ServiceStackでNagleのアルゴリズムを無効にする方法は?
ServiceStack 3.9.71.0 を使用していますが、現在、WAN 接続を介したクライアントで原因不明の遅延の問題が発生しています。
非常に小さいペイロード (<100 バイト) の応答が 200ms 以上後に受信されます。
地理的な距離のため、リンクの往復時間 (RTT) は約 40 ミリ秒です。これは、他のホストに ping を実行し、単純なエコー サービスを使用して TCP 接続の遅延をテストすることで確認されています。
ping テストとエコー テストの両方で、期待どおりのレイテンシが示されています。ServiceStack ホストからの応答を取得するのに、予想よりもはるかに時間がかかります。
次のことを確認しました。
- WAN リンクが容量の 25% でのみ実行されている (輻輳なし)
- WAN リンクでは QOS は使用されません
- 同じホストは、ローカル ネットワーク上の別のホストからの同じ要求に対して高速に応答します
- 遅延は、リクエストを処理するコードによって引き起こされるものではありません
現在、Nagle のアルゴリズムに出くわし、それが WAN ネットワーク上の小さな要求の遅延を意味する可能性があることを発見しました ( http://blogs.msdn.com/b/windowsazurestorage/archive/2010/06/25/nagle-s-algorithm-is -not-Friendly-towards-small-requests.aspx )。
.NET では、設定によって無効にすることができますTcpClient.NoDelay = true
( https://msdn.microsoft.com/en-us/en-US/library/system.net.sockets.tcpclient.nodelay(v=vs.110).aspx )。
ServiceStack の TCP 処理でこれを無効にするにはどうすればよいですか?
編集:これはHttpWebRequest is slow with chunked dataの複製だとは思いません。上記の質問はHttpWebRequest
、ServiceStack で使用されていないものをカバーしています。ServiceStack はHttpListener
、前述の によって制御/管理されているものも使用しServicePointManager
ます。ServicePointManager.UseNagleAlgorithm = false
設定によって問題が解決するかどうかをテストします。
sockets - nginx で TCP_QUICKACK を使用する
私は最近、サーバー側の遅延 ACK とクライアント側の Nagle のアルゴリズムの組み合わせに悩まされていました。 05/know-a-delay-nagles-algorithm-and-you/
これを修正する最も簡単な方法は、クライアント側で TCP_NODELAY を使用することです (または、TCP_CORK がこのケースでも機能するはずです)。ただし、クライアントを直接制御できないため、サーバー側の修正を試みたいと考えています。サーバーはすぐに ACK を返し、クライアント側の Nagle のアルゴリズムが遅延なく次のパケットを送信するため、ここでは TCP_QUICKACK オプションがうまくいくようです。
驚いたことに、以前にこれを試した人への言及は見つかりませんでした。それは悪い考えですか? このオプションは nginx の構成を介して利用できるようには見えないため、nginx に直接パッチを適用するのが最善の策です (おそらくhttp://hg.nginx.org/nginx/file/dcae651b2a0c/src/http/ngx_http_request. c#l3025 )?
ありがとう!
c# - C# サーバー - TCP/IP ソケットの効率
良い一日を!
私はクローズド ソースのゲームのオープン ソース サーバーに取り組んでいます - ゲームは TCP/IP ソケットを使用して動作します (UDP の代わりに、doh...)。
私の現在のプログラム構造(ダムダウン):
コアスレッド
- 新しい接続を受け取り、新しいクライアント オブジェクトを作成します。
クライアント オブジェクト
IOloop (独自のスレッドで実行)
- ソケットからデータを取得し、パケットを処理します。(一度に 1 パケット)
- 他のスレッドからバッファリングされたデータを送信 (一度に 1 パケット)
クライアントが独自のスレッドである場合、クライアントはすぐに (遅延なしで) データを送信します。
プログラムに大きな欠陥があることに気付きました。主に、データの送信が非常に遅いです。同期的に、パケットごとにデータを送信するためです。(Socket.Send(byte[] バッファ))
データを遅滞なく、非同期で、すぐに送信したいと考えています。
パケットを送信するたびに新しいスレッドを作成しようとしました (そのため、各パケットは独自のマネージド スレッドで送信されます) が、これは非常に面倒でした。
私の現在のシステムは、nagle アルゴリズムを無効にした同期送信を使用していますが、これにはボトルネックの欠陥があります。1 つのパケットを送信し、TCP が確認するまで操作ブロックを送信してから、次のパケットを送信します... 100 ミリ秒ごとに 10 パケットを簡単に発行できます。パケットの送信には 400 ミリ秒かかり、これがバックアップして壊れます。もちろん、ローカル ホストではこの問題は発生しません。
それで、私の質問: データの複数の小さなパケットを送信する最良の方法は何でしょうか? 前後の遅延を減らすために、すべての IO スレッド ループの最後に送信するデータを 1 つの大きなバイト バッファーにマージすることを考えています。遅れます。
同期送信はどのように機能しますか? 私が信じているように、データが受信者によって正しく受信されたことを確認するまでブロックしますか? 確認を待たずにこれを行う方法はありますか? パケットはすべて順番どおりに正しく送信する必要があることは理解しています (プロトコル仕様に従って)。
c# - TCP NO_DELAY + 失われたヘッダー + TCP 再送信
この場合、奇妙な状況が見られます。
- HTTP リクエストは、TCP フラグ NO_DELAY (つまり、Nagle アルゴリズムが無効) で送信されます。
- WireShark は、HTTP 動詞とヘッダーを含む TCP パケットをキャプチャしません。HTTP 本文を含むパケットのみが表示されます (パケットは失われますか?)。
- リモート ホストは、すべてのデータが確認されているわけではないことを示す ACK で応答します。
- TCP 再送信が発生し、HTTP 動詞とヘッダーが WireShark によってキャプチャされるようになりました。
その他の注意事項:
- Nagle アルゴリズムが ON の場合、パケットの損失や再送信は見られません。
- この問題は 2 つの異なるネットワークで検証されているため、この問題はネットワーク環境とはほとんど関連していません (ホストが仮想マシンであるという事実を除いて)。
- リクエストは c# HttpClient (.NET 4) を使用して行われます。
- HTTP 本体のサイズが役割を果たしているようです - 比較的小さなパケットでは問題ありません。
そのため、NO_DELAY によって、HTTP ヘッダー/動詞が内部にある TCP パケットが失われるという奇妙な動作が発生するようです。
何かアドバイス?
javascript - Nagle のアルゴリズム クライアント側/JavaScript を無効にする
Nagle のアルゴリズムはクライアント側でも無効にする必要がありますか? この場合、JavaScript だけで Nagle のアルゴリズムを無効にする方法は見つかりませんでした。
Raspbian OS でホストされている PHP CLI サーバー (Windows 7 と Ubuntu でも同じ結果でホストされています) から、websocket 経由でデータをストリーミングしようとしています。このサーバーはソケットを正常に作成し、複数の接続を受け入れ、TCP_NODELAY フラグを設定しました (socket_get_option のみで検証)。
ほとんどのプラットフォームでは、この TCP_NODELAY フラグが設定されているかどうかに関係なく、データは凝集することなくストリーミングされます。ただし、Windows 7 の Chrome と Firefox では、データはチャンクで到着します(明らかな 0.2 秒の遅延があります)。Windows 8 、Linux、iOS、および Windows 7 の Internet Explorer 11: この問題はまったく発生しません。
http://www.13willows.com/hovelme/script/serverControl.php これがテスト Web サイトです。[接続] をクリックし、[ゲームを表示] をクリックすると、現在のパケットが 50 ミリ秒ごとに 1 から 20 に着実に増加するのがわかります。 . ただし、一部のクライアントでは、約 200 ミリ秒ごとに一度に 4 つジャンプします。
これを止めるためのアイデアはありますか?node.js / socket.io を使用すると、このような問題が修正され、ユーザーのブラウザーからコードを実行できるようになりますか?
php - PHPエコー文字列が長すぎます
これが PHP のバグなのかサーバー構成なのかはわかりませんが、長さが 2,000,000 文字をはるかに超える文字列をエコーできないようです。ページがハングするだけです。
これはローカル マシンでは機能しますが、ライブ サーバーでは機能しません。
str_split を使用して文字列を配列に分割し、各部分を個別に出力しようとしましたが、それでもうまくいきません。
これが Nagle のアルゴリズムと TCP/IP バッファリングに関係しているというコメントもいくつか見ましたが、私はまだ賢明ではありません。
助けてください!
algorithm - Nagle のアルゴリズム、ACK 遅延、および Rlogin エコー
プロトコルに関する特定の質問が話題になっているため、ここでも質問するように提案されましたが、誰かが興味を持っている場合に備えて、質問にはServerFaultに関する小さな報奨金もあります。
TCP データ フロー、Delayed ACK、およびNagle のアルゴリズムについて読んでいます。
これまでのところ、次のことを理解しています。
- TCP での遅延 ACKの実装は、受信したセグメントの確認応答に遅延を作成して、アプリケーションが確認応答とともにデータを書き込む機会を与えることで、空の ACK パケットの送信を回避し、ネットワークの輻輳に寄与します。
- Nagleのアルゴリズムの実装では、別の小さなセグメントがまだ確認されていないときに、小さな TCP セグメントを送信することはできないと述べています。これにより、トラフィックが数個のtinygramでロードされるのを回避できます。
たとえば Rlogin などの一部の対話型アプリケーションでは、Nagle のアルゴリズムと遅延 ACKが「競合」する可能性があります。
Rlogin はキーボード入力を入力するとサーバーに送信し、一部のキー ( F1など) は 1 バイト以上を生成します ( F1 = Escape + 左角括弧 + M)。これらのバイトは、1 つずつ TCP に配信される場合、異なるセグメントで送信できます。
サーバーは、シーケンス全体を取得するまでエコーで応答しないため、すべての ACK が遅延します (アプリケーションからのデータが期待されます)。一方、クライアントは、最初のバイト確認応答を待ってから、次のバイト確認応答を送信します ( Nagle のアルゴリズムを尊重します)。この組み合わせにより、最終的に「遅延」Rlogin が発生します。
Rloginで送信される F1 キーと F2 キーを以下tcpdump
に示します。
今疑問: 私が読んだページには、サーバーがキーシーケンス全体を取得する前にエコーで応答しないと記載されていますが、キャプチャされたパケットはtcpdump
、キーがそれぞれの ACK でエコーされていることを示しています (最初の応答は 2 です) ESCからのエコーは 2 文字 (キャレット + 左角かっこ) であるため、バイト長です。
データがアプリケーションから TCP (エコー応答) に送信されている場合、ACK が遅れているのはなぜですか? 述べられたことによると、サーバーがエコーする前に完全なシーケンスを待っていることについて、ACK には、シーケンス全体のエコーが含まれる最後の ACK までエコーが含まれていないはずではありませんでしたか?
編集:tcpdump
Nagle のアルゴリズム (TCP_NODELAY フラグ) を使用しない、変更された Rlogin
の出力は次のとおりです。
Nagle のアルゴリズムがオフになっている場合でも、セグメント 4 で ~0.2ms の遅延が見られます (したがって、すべての特別なキー バイトが一緒に到着し、一緒に処理できます)。セグメント 6 では、失われたセグメントの再送信をサーバーが再処理して再パケット化するのに時間がかかるため、約 0.2 ミリ秒の遅延を特定できませんが、この遅延は 2 秒を超えています。
F2キーの例では、セグメント 11 で約 0.2 ミリ秒の遅延も確認できます。セグメント 11 の直後に送信された可能性があるため、セグメント 12 で識別できません。
これは@MattTimmersansの答えが正しいことを示しており、本がセグメントの遅延を誤解している可能性があります。これらは、データが TCP スタックに送信されないために ACK が遅延するのではなく、実際にはネットワーク メディアの特性である可能性があります。
参照: http://people.na.infn.it/~garufi/didattica/CorsoAcq/Trasp/Lezione9/tcpip_ill/tcp_int.htm
nagle - 受信側の Nagle アルゴリズム
私は理解していると思います (しかし、私は間違っているかもしれません ;-)) 送信者側の Nagle アルゴリズムの原則: メッセージは、前のパケットが確認されていない限り、送信者側の IP スタックによって遅延される可能性があります。
それにもかかわらず、単一のパケットが送信され、いくつかのアプリケーション メッセージ (Mn、Mn+1、Mn+2 など) が含まれている場合、受信者はどのようにして異なるアプリケーション メッセージ (Mn、Mn+1、Mn+2) を分割することができますか?この単一のパケット?
受信者に警告するフラグがパケットに含まれていますか? PSHフラグと関係ありますか?シーケンス番号または確認番号に関連していますか? (私はそうは思わない)
受信者側でメッセージを分割するのは誰ですか? IPスタックまたはアプリケーション? IPスタックだと思いますが、有効にする標準オプションはありますか?
送信者と受信者は共通の構成を送信しますか? (たとえば、NO_DELAY オプションの非アクティブ化について?)
あなたのサポートに感謝します。