14

我有一个使用 urllib 定期获取 url 的程序,我看到间歇性错误,例如:

I/O 错误(套接字错误):[Errno 111] 连接被拒绝。

它在 90% 的时间里都能正常工作,但在其他 10% 的时间里它都失败了。如果在失败后立即重试获取,则成功。我无法弄清楚为什么会这样。我试图查看是否有可用的端口,它们是可用的。任何调试想法?

有关其他信息,堆栈跟踪是:

File "/usr/lib/python2.6/urllib.py", line 203, in open 
    return getattr(self, name)(url)

File "/usr/lib/python2.6/urllib.py", line 342, in open_http
    h.endheaders()

File "/usr/lib/python2.6/httplib.py", line 868, in endheaders
    self._send_output()

File "/usr/lib/python2.6/httplib.py", line 740, in _send_output
    self.send(msg)

File "/usr/lib/python2.6/httplib.py", line 699, in send
    self.connect()

File "/usr/lib/python2.6/httplib.py", line 683, in connect
    self.timeout)

File "/usr/lib/python2.6/socket.py", line 512, in create_connection
    raise error, msg

编辑 - 谷歌搜索不是很有帮助,我从中得到的是我从中获取的服务器有时会拒绝连接,我如何验证它不是我的代码中的错误,这确实是这种情况?

4

5 回答 5

40

使用像Wireshark这样的数据包嗅探器来查看发生了什么。您需要看到一个带有 SYN 标记的数据包传出,一个带有 SYN+ACK 标记的传入,然后是一个带有 ACK 标记的传出。之后,该端口在本地被认为是开放的。

如果您只看到第一个数据包并且在等待几秒钟后出现错误消息,则另一方根本没有回答(例如:拔掉电缆、服务器过载、错误的数据包被丢弃)并且您的本地网络堆栈中止连接尝试. 如果您看到 RST 数据包,则主机实际上拒绝了连接。如果您看到“ICMP Port unreachable”或主机无法访问的数据包,防火墙或目标主机会通知您该端口实际上已关闭。

当然,您不能期望该服务始终可用(考虑您和数据之间的所有故障点),因此您应该稍后再试。

于 2010-04-01T13:05:49.123 回答
11

得到一个 ECONNREFUSED errno 意味着你的内核在另一端被拒绝连接,所以如果它是一个错误,它要么在你的内核中,要么在另一端。您可以做的是以非常具体的方式捕获错误并稍后再试一次,因为这似乎有效:

# This is Python > 2.5 code
import errno, time

for attempt in range(MAXIMUM_NUMBER_OF_ATTEMPTS):
    try:
        # your urllib call here
    except EnvironmentError as exc: # replace " as " with ", " for Python<2.6
        if exc.errno == errno.ECONNREFUSED:
            time.sleep(A_COUPLE_OF_SECONDS)
        else:
            raise # re-raise otherwise
    else: # we tried, and we had no failure, so
        break
else: # we never broke out of the for loop
    raise RuntimeError("maximum number of unsuccessful attempts reached")

用您喜欢的数字替换两个全大写常量。

于 2010-04-01T13:00:58.043 回答
3

我以前在我的 EC2 实例上遇到过这个问题(我正在使用 couchdb 来提供资源——我正在考虑将来使用 Amazon 的 S3)。

要检查的一件事(假设 Ec2)是 couchdb 端口已添加到您的安全策略中的开放端口中。

我具体遇到

“[Errno 111] 连接被拒绝”

在实例停止和启动时通过 EC2。问题似乎是 pidfile 竞赛。我的解决方案是通过以下方式(完全正确地)杀死 couchdb:

pkill -f couchdb

然后重新启动:

/etc/init.d/couchdb restart
于 2012-01-26T01:56:51.440 回答
2

我不确定是什么原因造成的。您可以尝试查看您的 socket.py(我的版本不同,因此跟踪中的行号不匹配,恐怕其他一些细节也可能不匹配)。

try: ... except: ... 无论如何,将您的 url 获取代码放在一个块中,并通过短暂的暂停和重试来处理它似乎是一个好习惯。您尝试获取的 URL 可能已关闭或加载过多,而且您只能通过重试才能处理这些内容。

于 2010-04-01T07:54:40.807 回答
1

似乎服务器运行不正常,因此请确保使用终端

telnet ip port

例子

telnet localhost 8069

它将返回已连接到本地主机,因此表明连接没有问题,否则它将返回连接被拒绝 ,表明连接有问题

于 2017-06-22T06:31:34.250 回答