关于python:web应用程序在ssl.py中自我挂起几个小时

Web app hangs for several hours in ssl.py at self._sslobj.do_handshake()

我使用的是python 2.7.5。我有一个每隔几分钟查询一次API的Web应用程序,它已经成功运行了大约一天。然而,在把它搁置几个小时后,我回来发现我的程序停滞了好几个小时没有任何活动。我退出程序,发现在一次API调用期间,它在SSL握手方法中停滞了大部分时间。

这是回溯:

1
2
3
4
5
...
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()

我做了一点研究,似乎这是Python2.6中的SSL库的问题,但后来它被修复了。我想知道为什么我的程序在这里被卡住而没有抛出异常或任何东西。

如果有一种方法可以为ssl握手方法设置超时,我很乐意这样做,因为我想避免我的程序被无限期地停止,不再发生类似的事情。我正在使用请求HTTP库,如果这很重要的话,这是在mac osx 10.9上运行的。建议?

编辑:我做了一些研究,似乎其他人对SSL有这个特定的问题,尽管在2.6中实现了"修复"。然而,还不确定解决方案是什么。感谢您的帮助。

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


在浏览了堆栈溢出的python部分之后,我发现了一些可能无法解决导致问题的核心问题的东西,但绝对可以很好地处理出现此问题的任何情况。下面的问题有各种各样的解决方案,如果函数完成时间过长,这些解决方案将引发某种异常。这就是我最终解决这个问题的方法。最重要的答案是,只有Unix,但是还有一些其他平台使用线程并在每个平台上工作:

Timeout function if it takes too long to finish

这是一个奇怪的问题,事实上很难重现。在数千次API调用之后,我只见过两次。我认为有人不太可能找到比这个更好的解决方案,这是一种黑客,但肯定能解决问题。您可以抛出异常,然后再次尝试SSL连接,或者继续使用程序的另一部分。

我想我的答案现在就足够了,但如果有人有更好的东西,请随时提出。老实说,似乎唯一解决底层问题的方法可能是在实际的ssl.py库中修复bug,但我不可能确定。


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