我的Python程序运行几个小时后总是导致互联网断开,如何调试修复这个问题?

2 投票
2 回答
997 浏览
提问于 2025-04-16 09:57

我正在写一个Python脚本,用来检查和监控几个服务器或网站的状态,比如响应时间等。这是一个图形界面的程序,我用不同的线程来检查不同的服务器或网站。每个线程的基本结构是一个无限循环,每隔15到30秒就请求一次那个网站。如果网站或服务器有变化,每个线程会启动一个新线程来进行更详细的检查,比如请求更多的页面等。

问题是,我的互联网连接在这个脚本运行几个小时后总是会被堵住、卡住或者搞乱。具体情况是,我的脚本在请求页面时总是出现urlopen错误,提示超时,而我的Firefox浏览器也无法打开任何网站。但奇怪的是,一旦我关闭脚本,互联网连接立刻恢复正常,这意味着我可以通过浏览器访问任何网站,所以肯定是脚本引起了这个问题。

我仔细检查了程序,甚至使用del来删除任何已经使用的连接,但问题依然存在。我只使用了urllib2、urllib和mechanize来进行网络请求。

有没有人知道为什么会发生这种情况?我该如何调试这个问题?有没有什么工具可以在这种情况发生时检查我的网络状态?这个问题真的困扰我很久了……

顺便说一下,我是在VPN后面,这和这个问题有关系吗?虽然我不认为有关系,因为每次脚本关闭后我的网络总是能恢复,而且在整个过程中VPN连接似乎也没有掉线。

[更新:]

我刚找到更多关于这个问题的信息,当我的程序导致互联网连接不好的时候,其实并不是完全“断掉”,我的意思是,我无法在浏览器中打开任何网站,或者总是收到urlopen错误提示超时,但我仍然可以在命令行中使用“ping google.com”得到回复。而当我手动断开VPN连接然后重新拨号时,即使不关闭我的程序,它也开始正常工作,我也可以通过浏览器上网。为什么会这样呢?

2 个回答

0
  • 你可能创建的线程比你想象的要多——可以通过监控 threading.active_count() 的结果来检查这一点。

  • 如果可以的话,试着排除你这边的VPN问题(或者把相关的代码部分发出来,这样我们可以测试一下)。

  • (网络礼仪)如果你还没有这样做,建议每个监控的网站/主机只使用 network.http.max-connections-per-server 线程。

  • (供参考)urlopen 返回的是一个类似文件的对象——使用 .close()del 来处理这个对象,否则这个连接会一直处于 CLOSE_WAIT 状态,直到超时。

希望这些建议能对你有所帮助。

3

这可能不是问题的根源,但在处理打开资源的事情时,比如文件或网址,使用上下文管理器总是个好主意。

从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块结束时,连接会被关闭并删除,你就不需要再操心这个了。:-)

撰写回答