1

select.epoll を使用してクライアントの受信データを監視する PyPy 経由で実行されている Python サーバー アプリがあります。

データの準備ができたら、クライアントをループしてデータをすべて受信し、(必要に応じて) 行に分割して処理します。

行が「~」の場合、クライアントが ping 応答として解釈する sock.send("~\n") を呼び出すだけです。

問題は、私の個人的な経験では、ping が奇妙に非常に高く、奇妙に非常に変動しやすく、90 ミリ秒から約 3000 ミリ秒の範囲で、300 ~ 1000 ミリ秒が平均であることです。継続的に ping を実行すると、さまざまな場所でジャンプする結果が得られます。(サーバーへの「実際の」ping は約 85 ミリ秒です。)

cProfile を使用して、速度を低下させるものがあるかどうかを確認しました。得られた結果は次のとおりです。

Thu Aug 15 04:05:56 2013    profile.out

     17401043 function calls (17399987 primitive calls) in 815.728 seconds

Ordered by: cumulative time
List reduced from 960 to 25 due to restriction <25>

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    1    0.000    0.000  815.728  815.728 <string>:1(<module>)
    1    0.000    0.000  815.728  815.728 /root/app/src/serv/appserver/main.py:28(main)
    1    0.302    0.302  814.608  814.608 /root/app/src/serv/appserver/server.py:214(main_loop)
 2457  806.185    0.328  806.185    0.328 {method 'poll' of 'select.epoll' objects}
 2067    0.070    0.000    6.069    0.003 /root/app/src/serv/appserver/client.py:89(read)
 2274    0.013    0.000    5.875    0.003 /root/app/src/serv/appserver/client.py:150(handle_read_line)
 2264    0.062    0.000    5.600    0.002 /root/app/src/serv/appserver/client.py:164(handle_client_line)

私は Python のプロファイリングの経験はありませんが、実行時間の 815 秒のうち 806 秒がポーリングに費やされたように見えます。したがって、応答時間が長くなるのは、オーバーロードされたり、他の場所で時間を浪費したりするためではありません。

応答時間が非常に長くなる原因として、他に何が考えられますか?

ソケット初期化コード:

self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.server_socket.bind(bind)
self.server_socket.listen(5)
self.server_socket.setblocking(0)

編集: TCP_NODELAY ソケット オプションを設定しました。結果は今では著しく改善されていますが、それでもかなり悪いです。まだ90ミリ秒から500ミリ秒、1000ミリ秒に飛び回っています。

4

0 に答える 0