我有以下已使用大约一年的代码:
import urllib2
req = urllib2.Request('https://somewhere.com','<Request></Request>')
data = urllib2.urlopen(req)
print data.read()
最近,出现了一些随机错误:
urllib2.URLError: <urlopen error [Errno 111] Connection refused>
<urlopen error [Errno 110] Connection timed out>
失败的原因是:
Traceback (most recent call last):
File "test.py", line 4, in <module>
data = urllib2.urlopen(req).read()
File "/usr/lib/python2.7/urllib2.py", line 126, in urlopen
return _opener.open(url, data, timeout)
File "/usr/lib/python2.7/urllib2.py", line 400, in open
response = self._open(req, data)
File "/usr/lib/python2.7/urllib2.py", line 418, in _open
'_open', req)
File "/usr/lib/python2.7/urllib2.py", line 378, in _call_chain
result = func(*args)
File "/usr/lib/python2.7/urllib2.py", line 1215, in https_open
return self.do_open(httplib.HTTPSConnection, req)
File "/usr/lib/python2.7/urllib2.py", line 1177, in do_open
raise URLError(err)
urllib2.URLError: <urlopen error [Errno 111] Connection refused>
以上错误是随机发生的,脚本可以第一次成功运行,但是第二次运行失败,反之亦然。
我应该怎么做才能调试并找出问题的根源? 如何知道端点是否消耗了我的请求并返回了响应但从未到达我?
用telnet
我只是用telnet进行了测试,有时成功了,有时却没有,就像我的Python一样。
成功时:
$ telnet somewhere.com 443
Trying XXX.YY.ZZZ.WWW...
Connected to somewhere.com.
Escape character is '^]'.
Connection closed by foreign host.
在拒绝的连接上:
$ telnet somewhere.com 443
Trying XXX.YY.ZZZ.WWW...
telnet: Unable to connect to remote host: Connection refused
超时时:
$ telnet somewhere.com 443
Trying XXX.YY.ZZZ.WWW...
telnet: Unable to connect to remote host: Connection timed out
最佳答案
问题
问题出在网络层。以下是解释的状态代码:
Connection refused
:对等方未监听您要连接的相应network port。这通常意味着防火墙正在主动拒绝连接,或者相应的服务未在另一个站点上启动或过载。 Connection timed out
:在尝试建立TCP连接的过程中,在给定的时间限制内,另一端没有响应。在urllib的上下文中,这也可能意味着HTTP响应未及时到达。有时,这也可能是由防火墙引起的,有时是由于网络拥塞或远程(甚至本地)站点上的繁重负载引起的。 在上下文中
就是说,这可能不是您脚本中的问题,而是在远程站点上。如果偶尔发生,则表明另一个站点存在负载问题,或者到另一个站点的网络路径不可靠。
另外,由于这是网络的问题,您无法分辨另一端发生了什么。数据包可能会在一个方向上正常传输,而在另一个方向上丢失(或路由错误)。
这也不是(直接)DNS问题,它会引起另一个错误(名称或服务未知或类似问题)。但是,可能将DNS配置为在每个请求上返回不同的IP地址,这将在每次连接尝试中将您(DNS缓存留给您)连接到不同的地址主机。反过来,某些主机可能配置错误或过载,从而导致上述问题。
调试这个
正如另一个答案所建议的那样,使用数据包分析器可以帮助调试问题。但是,除了数据包能够准确反射(reflect)错误消息的内容之外,您将看不到其他内容。
要排除网络阻塞问题,可以使用
mtr
或 traceroute
甚至 ping
之类的工具来查看数据包是否丢失到远程站点。请注意,如果您看到mtr丢失(以及与此相关的任何traceroute工具),由于ICMP的工作方式,您必须始终将发生丢失(从您到远程的路由)中发生故障的第一台主机视为一个丢包的主机。 。如果长时间仅在最后一跳丢失了数据包(例如100个数据包),则该主机肯定有问题。如果您发现此行为持续存在(数天),则可能需要与管理员联系。路由中途的丢失通常对应于网络拥塞(可能是由于维护),您无能为力(除了向ISP提示缺少冗余外)。
如果网络拥塞不是问题(例如丢失的数据包不超过5%),则应与远程服务器管理员联系,以找出问题所在。他也许能够在系统日志中查看相关信息。与在本地站点上运行数据包分析器相比,在远程站点上运行数据包分析器也可能更具启发性。绝对建议使用
netstat -tlp
检查端口是否打开。
关于python - 如何调试导致连接被拒绝或连接超时的原因?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12145536/