19

我正在使用 Python 2.7.5。我有一个网络应用程序,它每隔几分钟就会查询一次 API,并且在最后一天左右一直在成功运行。然而,在让它静置几个小时后,我回来发现我的程序停滞了几个小时没有任何活动。我退出了程序,发现在其中一个 API 调用期间,它在 ssl 握手方法中的大部分时间都停滞不前。

这是回溯:

...
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 143, in __init__
  self.do_handshake()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 305, in do_handshake
  self._sslobj.do_handshake()

我做了一些研究,这似乎是 Python 2.6 中 SSL 库的问题,但它已得到修复。我想知道为什么我的程序没有抛出异常或任何东西就卡在这里了。

如果有办法为 SSL 握手方法设置超时,我很乐意这样做,因为我想避免我的程序再次因类似的事情而无限期地停止。我正在使用 Requests HTTP 库,它在 Mac OSX 10.9 上运行,如果这很重要的话。建议?

编辑: 我做了一些研究,似乎其他人在 SSL 方面遇到了这个特定问题,尽管在 2.6 中实施了“修复”。但是,尚不确定解决方案是什么。任何帮助表示赞赏。

编辑 3: 添加了我的解决方案作为这个问题的答案。

4

2 回答 2

7

浏览 Stack Overflow 的 Python 部分后,我发现了一些可能无法解决导致问题的核心问题,但绝对足以处理任何出现此问题的情况。以下问题有各种解决方案,如果一个函数需要太长时间才能完成,它们会抛出某种异常。这就是我最终解决这个问题的方法。最佳答案是仅限 UNIX,但是还有一些其他的使用线程并在每个平台上工作:

超时功能,如果完成时间过长

这是一个奇怪的问题,老实说很难重现。在成千上万的 API 调用之后,我只看到过两次。我认为不太可能有人会找到比这个更好的解决方案,这有点像 hack,但绝对可以解决问题。您可以抛出异常,然后再次尝试 SSL 连接,或者继续执行程序的另一部分。

我认为我的回答现在就足够了,但是如果有人有更好的东西,请随时提供。老实说,似乎对潜在问题的唯一修复可能是实际 ssl.py 库中的错误修复,但我无法肯定地说。

于 2013-11-15T05:53:24.973 回答
5

我遇到了这个问题,并且能够使用socket.setdefaulttimeout解决它。socket.setdefaulttimeout修改调用后创建的所有套接字的行为,如果套接字封装在库代码中,这很方便。如果您有权访问特定的 SSL 套接字,您可能可以使用socket.settimeout.

于 2015-06-11T05:05:52.897 回答