jam*_*esc 12 python sockets dns python-requests
在与各种Web服务进行通信的Django项目上运行Python,我们遇到一个问题,偶尔请求大约需要5秒而不是通常的<100毫秒.
我把这个缩小到了socket.getaddrinfo函数的时间- requests当我们连接到外部服务时调用它,但它似乎也影响了集群中Postgres数据库框的默认Django连接.当我们uwsgi在部署后重新启动时,第一个进入的请求将花费5秒钟来发送响应.我也相信我们的芹菜任务定期需要5秒,但我还没有添加statsd计时器跟踪.
我写了一些代码来重现这个问题:
import socket
import timeit
def single_dns_lookup():
start = timeit.default_timer()
socket.getaddrinfo('stackoverflow.com', 443)
end = timeit.default_timer()
return int(end - start)
timings = {}
for _ in range(0, 10000):
time = single_dns_lookup()
try:
timings[time] += 1
except KeyError:
timings[time] = 1
print timings
Run Code Online (Sandbox Code Playgroud)
典型的结果是 {0: 9921, 5: 79}
我的同事已经指出了围绕ipv6查找时间的潜在问题,并将其添加到/etc/gai.conf:
precedence ::ffff:0:0/96 100
Run Code Online (Sandbox Code Playgroud)
这肯定改进了curl我们使用的非Python程序的查找,但不是来自Python本身.服务器盒正在运行Ubuntu 16.04.3 LTS,我可以在Python 2的vanilla虚拟机上重现这一点.
我可以采取哪些步骤来提高所有Python查找的性能,使它们可以<1s?