ソケット フラッシュ動作に関連していると思われる発信メッセージにかなりの遅延がある問題を解決しようとしています。私は、quickfixj イニシエーターからアクセプターへの発信 FIX メッセージのパケット キャプチャを行ってきました。
環境を要約すると、Java イニシエーターは、別のサーバー上のサーバー ソケットへのソケット接続を確立します。どちらのサーバーも Redhat Enterprise Linux 5.10 を実行しています。インターフェイスの netstat からの MSS は 0 です。NIC の MTU はすべて 1500 です (ループバック インターフェイスでは無限だと思います)。アプリケーション側では、メッセージは quickfixj によってバイト配列にエンコードされ、ソケットに書き込まれます。ソケットは、TCP_NODELAY を有効にして構成されています。
ループバック インターフェイスを使用してイニシエーターと同じサーバーでアクセプター (ServerSocket) を実行すると、送信側のレイテンシーがないため、レイテンシーの原因としてアプリケーションを排除できるとほぼ確信しています。これは、ループバック インターフェイスを使用したパケット キャプチャ エントリの例です。
"No.","Time","Source","Destination","Protocol","Length","SendingTime (52)","MsgSeqNum (34)","Destination Port","Info","RelativeTime","Delta","Push"
"0.001606","10:23:29.223638","127.0.0.1","127.0.0.1","FIX","1224","20150527-09:23:29.223","5360","6082","MarketDataSnapshotFullRefresh","0.001606","0.000029","Set"
"0.001800","10:23:29.223832","127.0.0.1","127.0.0.1","FIX","1224","20150527-09:23:29.223","5361","6082","MarketDataSnapshotFullRefresh","0.001800","0.000157","Set"
"0.001823","10:23:29.223855","127.0.0.1","127.0.0.1","FIX","1224","20150527-09:23:29.223","5362","6082","MarketDataSnapshotFullRefresh","0.001823","0.000023","Set"
"0.002105","10:23:29.224137","127.0.0.1","127.0.0.1","FIX","825","20150527-09:23:29.223","5363","6082","MarketDataSnapshotFullRefresh","0.002105","0.000282","Set"
"0.002256","10:23:29.224288","127.0.0.1","127.0.0.1","FIX","2851","20150527-09:23:29.224,20150527-09:23:29.224,20150527-09:23:29.224","5364,5365,5366","6082","MarketDataSnapshotFullRefresh","0.002256","0.000014","Set"
"0.002327","10:23:29.224359","127.0.0.1","127.0.0.1","FIX","825","20150527-09:23:29.224","5367","6082","MarketDataSnapshotFullRefresh","0.002327","0.000071","Set"
"0.287124","10:23:29.509156","127.0.0.1","127.0.0.1","FIX","1079","20150527-09:23:29.508","5368","6082","MarketDataSnapshotFullRefresh","0.287124","0.284785","Set"
主な関心事は、1/ パケット長 (ここでは最大で 2851) にもかかわらず、各パケットに PUSH フラグが設定されていることです。2/ ここで測定しているレイテンシの尺度は、メッセージがエンコードされる前に設定された「送信時間」と、パケット キャプチャ時間の「時間」です。パケット キャプチャは、データを送信しているイニシエーターと同じサーバーで実行されています。10,000 パケットのパケット キャプチャの場合、ループバックを使用する場合、「SendingTime」と「Time」の間に大きな違いはありません。このため、送信遅延の原因であるアプリケーションを排除できると思います。
アクセプターが LAN 上の別のサーバーに移動すると、MTU サイズを超えるパケットの送信遅延が悪化し始めます。これは、キャプチャのスニペットです。
"No.","Time","Source","Destination","Protocol","Length","SendingTime (52)","MsgSeqNum (34)","Destination Port","Info","RelativeTime","Delta","Push"
"68.603270","10:35:18.820635","10.XX.33.115","10.XX.33.112","FIX","1223","20150527-09:35:18.820","842","6082","MarketDataSnapshotFullRefresh","68.603270","0.000183","Set"
"68.603510","10:35:18.820875","10.XX.33.115","10.XX.33.112","FIX","1223","20150527-09:35:18.820","843","6082","MarketDataSnapshotFullRefresh","68.603510","0.000240","Set"
"68.638293","10:35:18.855658","10.XX.33.115","10.XX.33.112","FIX","1514","20150527-09:35:18.821","844","6082","MarketDataSnapshotFullRefresh","68.638293","0.000340","Not set"
"68.638344","10:35:18.855709","10.XX.33.115","10.XX.33.112","FIX","1514","20150527-09:35:18.821","845","6082","MarketDataSnapshotFullRefresh","68.638344","0.000051","Not set"
ここで重要なことは、パケットが MSS (MTU から派生) よりも小さい場合、PUSH フラグが設定され、送信者の遅延がないことです。Nagle のアルゴリズムを無効にすると、これらの小さなパケットに PUSH が設定されるため、これは予想されることです。パケット サイズが MSS (この場合は 1514 のパケット サイズ) よりも大きい場合、パケットがキャプチャされた時間と SendingTime の差は 35 ミリ秒に跳ね上がります。
大きなパケット サイズのメッセージがループバック インターフェイスで 1 ミリ秒未満で送信されたため、この 35 ミリ秒の遅延がメッセージをエンコードするアプリケーションによって引き起こされた可能性は低いと思われます。キャプチャは送信側でも行われるため、MTU セグメンテーションも原因ではないようです。最も可能性の高い理由は、PUSH フラグが設定されていないため (パケットが MSS よりも大きいため)、OS レベルのソケットおよび/または TCP スタックが 35ms 後までフラッシュすることを決定していないことです。他のサーバーのテスト アクセプターは低速なコンシューマーではなく、同じ LAN 上にあるため、ACK はタイムリーです。
> MSSパケットの遅延を送信するこのソケットの原因について、誰かが何かポインタを与えることができますか? 米国の実際の取引相手に対して、この送信者の遅延は 300 ミリ秒にも達します。パケット サイズが MSS より大きい場合、以前の ACKS に関係なくすぐに送信されると思いました (ソケット バッファー サイズを超えない限り)。通常、Netstat は 0 のソケット q と風サイズを示し、起動時からでも、すべての > MSS パケットで問題が発生するようです。これは、ソケットが何らかの理由ですぐにフラッシュしないことを決定しているように見えますが、どのような要因がそれを引き起こす可能性があるかは不明です.
編集: EJP で指摘されているように、Linux にはフラッシュがありません。私が理解しているように、ソケット送信はデータをLinuxカーネルのネットワークバッファに入れます。そして、これらの非プッシュ パケットの場合、カーネルは前のパケットからの ack を待ってから配信しているようです。これは私が期待するものではありません.TCPでは、ソケットバッファがいっぱいになるまでパケットが配信されることを期待しています。