我有一个通过 PyPy 运行的 Python 服务器应用程序,它使用 select.epoll 来监视客户端的传入数据。
当数据准备好时,我会循环访问所有客户端,将其分成几行(如有必要)并进行处理。
如果该行是“~”,我只需调用 sock.send("~\n") 客户端将其解释为 ping 响应。
问题在于,根据我的个人经验,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 套接字选项。结果现在明显好转,但仍然很糟糕。仍然从 90ms 跳到 500ms 到 1000ms。