【发布时间】:2012-10-29 08:56:22
【问题描述】:
我有两台服务器(让我将它们命名为 A 和 B)。
事实:
- 它们具有相同的 CPU、内存、主板、硬盘驱动器、上行链路速度。
- 它们都在带有 Python 2.7.3 和 Django 最新版本的 Ubuntu 12.04 上。
- 它们还位于具有相同名称服务器设置的同一数据中心。
- 它们具有与名称服务器相似的 ping 和 traceroute 结果。
服务器 A 工作正常。我的问题是使用python连接互联网时服务器B非常慢。
以下是我在两台服务器上进行的测试(domain_list_1 和 domain_list_2 是两个列表,每个列表中包含 100 个唯一域):
测试一:
starttime = time.time()
for domain in domain_list_1:
ip = socket.gethostbyname(domain)
print '%.1f items per second' % (100/(time.time()-starttime))
>> Server A Results: 3.3 items per second
>> Server B Results: 0.7 items per second
测试二:
starttime = time.time()
for domain in domain_list_2:
os.system('nslookup %s > /dev/null' % domain)
print '%.1f items per second' % (100/(time.time()-starttime))
>> Server A Results: 3.3 items per second
>> Server B Results: 3.3 items per second
从测试二中可以看出,服务器 B 上的网络没有问题。
我用 urllib2 做了类似的测试,结果是一样的(服务器 A 没问题,但服务器 B 使用 urllib2 比使用 wget 或 curl 来做同样的工作要慢)。所以我相信这是一个Python问题。我只是不知道服务器 B 上的 Python 设置出了什么问题。
有没有办法可以剖析内部流程并找出代码的哪一部分减慢了整个流程?
提前谢谢你!
【问题讨论】:
-
“连接到互联网”与您所做的非常不同,即“按名称查找 DNS 条目”。您的名称解析系统可能在服务器 B 上配置错误。这不太可能是 Python 问题,因为 Python 只是调用操作系统。
-
@Greg,如果OS级别的名称解析有问题,如何解释nslookup比Python的socket.gethostbyname()快得多?
-
nslookup 会绕过本地解析器库,因为它特定于 DNS(请记住,名称可以通过多种方式解析,其中只有一种是 DNS)。检查
/etc/nsswitch.conf以了解如何查找主机名。 -
@Greg, /etc/nsswitch.conf on A & B 完全一样。
-
那么
hosts:的行是什么意思?该行列出的服务是解析器库检查主机名查找的内容。其中一个条目可能是dns,但可能还有其他条目(这可能会导致您的问题)。你也可以在strace下运行你的程序,看看额外的延迟在哪里(但这样可能很难追踪)。
标签: python performance networking dns gethostbyname