2016-07-03 11 views
2

私はUbuntu 16.04マシンでデータ収集システムを実行しています。リモートサイトに配置されているため、物理的な構成を変更する能力は限られています。私たちは、設定で簡単なテストを実行できる現場に誰かを持っています。Pythonソケット接続には、Ubuntuで9回の接続ごとに1秒の遅延があります。16.04

私たちはデータ取得を行うためにpythonスクリプトを実行しています。しかし、高いデータ転送速度では、データバッファで奇妙なバックアップが発生していました。デバッグの数時間後、我々は次のテストケースまで問題を絞り込むことができました:

for i in xrange(500): 
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    sock.connect(('1.2.3.4', 5678)) 
    sock.close() 

上記のコードはほとんどのサンプルは、ほぼ瞬時に実行する実行されますが、すべての第九のサンプルを実行するには、正確に1秒を要するとき。奇妙なことに、実際にデータを取ったとき、その期間はずっと短くなります.1つのテストでは650ms程度で、グリッチサンプルよりも前に接続が成功します(その場合、グリッチサンプルは650ms間隔の〜400msしかかかりません)。以下は両方のインスタンスの接続レイテンシと時間のプロットです。軸は秒である。)ここで

Latency between connections. connect-and-close in blue, system under load in red.

たちが試みたデバッグのサブセットであり、そして問題は、それぞれの場合に持続するかどうか。簡潔さのための謝罪;いずれかのステップが不明な場合は、フォローアップ情報を提供しています。 netcatを持つ

  • データ収集は:(データソースでテストすることはできませんNCリスナー、に対して)2台のUbuntu 14.04のマシン間
  • 実行Pythonスクリプトワークス:netcatをリスナーを実行している別のコンピュータへ
  • 接続ワークス、代わりに、収集コンピュータからのデータソースの:問題はclose()
  • コールshutdown()を持続します。問題は
  • を持続します。問題は、サーバーを実行するために asyncoreを使用してみました
  • を持続します
  • はスレッドでソケットを開くしようとしました:問題は
  • トグル様々なnet.ipv4.tcp_*カーネルパラメータを持続する:問題は上記のことから

を持続し、私は見分けることができました唯一の一貫性は、Pythonは、この特定のマシン上で実行されているということですこの問題に遭遇する。私はまだ別のUbuntu 16.04(またはそのほかの4.xカーネル)でこれをテストする機会がありませんでしたので、ネットワーキングスタックの変更に関係しているかどうかはわかりません。私はこの問題を診断しようとするために、さまざまなテストを実行し続けるが、任意のアイデアが評価されています!

更新:

ulimit -aの結果(何が変わったとして私に飛び出し)。

core file size   (blocks, -c) 0 
data seg size   (kbytes, -d) unlimited 
scheduling priority    (-e) 40 
file size    (blocks, -f) unlimited 
pending signals     (-i) 32053 
max locked memory  (kbytes, -l) 64 
max memory size   (kbytes, -m) unlimited 
open files      (-n) 1024 
pipe size   (512 bytes, -p) 8 
POSIX message queues  (bytes, -q) 819200 
real-time priority    (-r) 0 
stack size    (kbytes, -s) 8192 
cpu time    (seconds, -t) unlimited 
max user processes    (-u) 32053 
virtual memory   (kbytes, -v) unlimited 
file locks      (-x) unlimited 

すぐにTIME_WAITテストを実行し、結果を送信します。私が実行したいもう一つのテストは、straceを使ってnetcatとpythonを実行して、ソケットと接続の引数が異なるかどうかを調べることです。

+0

'ulimit'を確認してください。私は、リモートサーバがそのレートですべての着信接続を処理する能力を持っていると仮定することができます接続の数にいくつかの制限要因がなければならないと思う。また、netcatを使用してTIME_WAITソケットを監視してください。接続が正しく閉じられていない可能性があります。そのような場合は、 'sock.setsockopt(socket.SOL_SOCKET、socket.SO_REUSEADDR、1)'を実行してください。進行状況について教えてください:) – purrogrammer

+0

リスニングキューの値は何ですか?サーバー側で?それがいっぱいになると、クライアントから送信されたsynが削除され、tcp再送信が行われます。このデフォルトは3秒です(システムが1秒に調整されている可能性があります)。確認するには、tcpdumpをキャプチャし、 – VenkatC

答えて

1

ありがとうございました。振り返ってみると、tcpdumpが最初にチェックしておかなければならないことは、私自身の判断で代用するVenkatに感謝します。

これはベンダーソフトウェアのバグのようです。 Tcpdumpは、pythonテストを実行しているときに、デバイスがハンドシェイクをプリエンプトし、発行された最後のデータクエリへの応答を再送信することを示しました。実際に、パケットが廃棄されてから1秒後にSYNが再送信され、サイクルが継続されました。

9パケットはレイテンシ(投稿されたプロットのドリフトによって示唆された)と一致しているようです - 応答はすぐにトリガされ、9番目のパケットを先取りしました。 netcat(例えば、printf "" | nc 1.2.3.4 5678)を使用した単一のリクエストがデータの再送信をトリガーします。

ベンダーと協力してこの問題を解決します。その間、私たちはsettimeoutを使用して、接続を再確立することによってタイムアウト例外を処理しようとします。

もう一度ありがとうございます!

関連する問題