3

我有两台服务器(让我将它们命名为 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 设置出了什么问题。

有没有办法可以剖析内部流程并找出代码的哪一部分减慢了整个流程?

先感谢您!

4

1 回答 1

2

根据 Greg 给出的建议,我查看了 strace 的输出,发现如下:

服务器 A:

12879 21:29:24.182590 connect(5, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("206.251.73.9")}, 16) = 0 <0.000035>
12879 21:29:24.182694 poll([{fd=5, events=POLLOUT}], 1, 0) = 1 ([{fd=5, revents=POLLOUT}]) <0.000018>
12879 21:29:24.182778 sendto(5, "'!\1\0\0\1\0\0\0\0\0\0\njanadrakka\3com\0\0\1\0\1", 32, MSG_NOSIGNAL, NULL, 0) = 32 <0.000040>
12879 21:29:24.182881 poll([{fd=5, events=POLLIN}], 1, 5000) = 1 ([{fd=5, revents=POLLIN}]) <0.067000>
12879 21:29:24.249987 ioctl(5, FIONREAD, [130]) = 0 <0.000022>
12879 21:29:24.250100 recvfrom(5, "'!\201\200\0\1\0\1\0\2\0\2\njanadrakka\3com\0\0\1\0\1"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("206.251.73.9")}, [16]) = 130 <0.000032>
12879 21:29:24.250287 close(5)          = 0 <0.000053>

服务器 B:

4850  21:28:55.501276 connect(5, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("206.251.73.9")}, 16) = 0 <0.000019>
4850  21:28:55.501348 poll([{fd=5, events=POLLOUT}], 1, 0) = 1 ([{fd=5, revents=POLLOUT}]) <0.000014>
4850  21:28:55.501419 sendto(5, "\346\10\1\0\0\1\0\0\0\0\0\0\fdeghatgostar\3com\0\0\1"..., 34, MSG_NOSIGNAL, NULL, 0) = 34 <0.000036>
4850  21:28:55.501506 poll([{fd=5, events=POLLIN}], 1, 5000) = 1 ([{fd=5, revents=POLLIN}]) <0.615731>
4850  21:28:56.117335 ioctl(5, FIONREAD, [129]) = 0 <0.000033>
4850  21:28:56.117429 recvfrom(5, "\346\10\201\200\0\1\0\1\0\2\0\2\fdeghatgostar\3com\0\0\1"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("206.251.73.9")}, [16]) = 129 <0.000011>
4850  21:28:56.117499 close(5)          = 0 <0.000009>

延迟发生在此系统调用上:

答: 12879 21:29:24.182881 poll([{fd=5, events=POLLIN}], 1, 5000) = 1 ([{fd=5, revents=POLLIN}]) < 0.067000 >

B: 4850 21:28:55.501506 poll([{fd=5, events=POLLIN}], 1, 5000) = 1 ([{fd=5, revents=POLLIN}]) < 0.615731 >

解决方案:

似乎延迟是由服务器 B 上的 IPv6 dns 查找引起的。但是,我仍然不确定为什么服务器 A 没有这样的问题,但是在服务器 B 上进行的以下更改解决了它。

将以下行添加到 /etc/sysctl.conf 并重新启动服务器。

net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

最后,感谢 Greg 的建议。

于 2012-11-09T05:49:01.213 回答