我的Python程序运行几个小时后总是导致互联网断开,如何调试修复这个问题?
我正在写一个Python脚本,用来检查和监控几个服务器或网站的状态,比如响应时间等。这是一个图形界面的程序,我用不同的线程来检查不同的服务器或网站。每个线程的基本结构是一个无限循环,每隔15到30秒就请求一次那个网站。如果网站或服务器有变化,每个线程会启动一个新线程来进行更详细的检查,比如请求更多的页面等。
问题是,我的互联网连接在这个脚本运行几个小时后总是会被堵住、卡住或者搞乱。具体情况是,我的脚本在请求页面时总是出现urlopen错误,提示超时,而我的Firefox浏览器也无法打开任何网站。但奇怪的是,一旦我关闭脚本,互联网连接立刻恢复正常,这意味着我可以通过浏览器访问任何网站,所以肯定是脚本引起了这个问题。
我仔细检查了程序,甚至使用del
来删除任何已经使用的连接,但问题依然存在。我只使用了urllib2、urllib和mechanize来进行网络请求。
有没有人知道为什么会发生这种情况?我该如何调试这个问题?有没有什么工具可以在这种情况发生时检查我的网络状态?这个问题真的困扰我很久了……
顺便说一下,我是在VPN后面,这和这个问题有关系吗?虽然我不认为有关系,因为每次脚本关闭后我的网络总是能恢复,而且在整个过程中VPN连接似乎也没有掉线。
[更新:]
我刚找到更多关于这个问题的信息,当我的程序导致互联网连接不好的时候,其实并不是完全“断掉”,我的意思是,我无法在浏览器中打开任何网站,或者总是收到urlopen错误提示超时,但我仍然可以在命令行中使用“ping google.com”得到回复。而当我手动断开VPN连接然后重新拨号时,即使不关闭我的程序,它也开始正常工作,我也可以通过浏览器上网。为什么会这样呢?
2 个回答
你可能创建的线程比你想象的要多——可以通过监控
threading.active_count()
的结果来检查这一点。如果可以的话,试着排除你这边的VPN问题(或者把相关的代码部分发出来,这样我们可以测试一下)。
(网络礼仪)如果你还没有这样做,建议每个监控的网站/主机只使用 network.http.max-connections-per-server 线程。
(供参考)
urlopen
返回的是一个类似文件的对象——使用.close()
或del
来处理这个对象,否则这个连接会一直处于 CLOSE_WAIT 状态,直到超时。
希望这些建议能对你有所帮助。
这可能不是问题的根源,但在处理打开资源的事情时,比如文件或网址,使用上下文管理器总是个好主意。
从Python 2.5开始,你可以这样处理文件:
with open('/tmp/filename', 'rt') as infile:
data = infile.read()
whatever(data)
这样在代码块结束时,文件会自动关闭。
不过,urllib2并不支持这种自动关闭,但你可以使用contextlib来帮忙:
>>> import contextlib
>>> with contextlib.closing(urllib2.urlopen('http://www.python.org')) as page:
... for line in page:
... print(line)
<html> blablablabla</html>
这样在with块结束时,连接会被关闭并删除,你就不需要再操心这个了。:-)