python - 如何调试导致连接被拒绝或连接超时的原因?

标签 python networking

我有以下已使用大约一年的代码:

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/

    相关文章:

    python - Pandas 删除值与列名相同的行

    python - 如何加载 PEM 编码证书链中的所有证书?

    python - 为什么我的 pandas DataFrame 列也是 Dataframes,而不是 Series?

    networking - Flash/Flex 中的 UDP 实时游戏可用 开源 RTMFP 实现

    docker - 无法从外部访问在 docker swarm 上运行的容器

    python - Seaborn 热图中的自定义调色板

    python - tkinter 中的 SQL 查询结果

    iphone - iPhone 应用程序可以在后台因重大位置变化而唤醒进行网络事件吗?

    c - lwIP 是否支持 Zeroconf?

    python - TCP 线程 python