Web应用程序在ssl.py中挂起几个小时在self._sslobj.do_handshake()

时间:2013-11-12 19:51:43

标签: python ssl pyopenssl

我正在使用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上运行,如果这很重要的话。建议?

修改 我做了一些研究,it seems that others have had this specific problem with SSL,尽管在2.6中实现了“修复”。但是,不确定解决方案是什么。任何帮助表示赞赏。

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

2 个答案:

答案 0 :(得分:6)

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

  

Timeout function if it takes too long to finish

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

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

答案 1 :(得分:5)

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