7

我的 python 程序使用 httplib2.Http 发出 http 请求。一旦我需要生成一个请求,我就会创建一个 httplib2.Http 对象,这样我的程序就会频繁地创建/销毁 httplib2.Http 对象。

我发现由于达到最大打开文件数,我的程序很容易崩溃。检查 /proc//fd,打开的套接字 fd 太多。这个问题让我不得不深入研究 httplib2 源代码。

然后我发现,在 httplib2.Http._conn_request 方法中,有这样的代码:

        else:
            content = ""
            if method == "HEAD":
                conn.close()
            else:
                content = response.read()
            response = Response(response)
            if method != "HEAD":
                content = _decompressContent(response, content)
        break

这表明只有当 http 方法为 HEAD 时才会关闭套接字。也许 httplib2 想以某种方式重用套接字。但是 Http 类没有 close() 方法。这意味着当我发出 Http 请求时,套接字在我的进程终止之前不会关闭。

然后我修改了代码:

        else:
            content = ""
            if method == "HEAD":
                conn.close()
            else:
                content = response.read()
            response = Response(response)
            if method != "HEAD":
                content = _decompressContent(response, content)
                conn.close() # I ADD THIS CLOSE
        break

在那之后,我的程序运行良好。

但是我仍然很好奇这是否真的是 httplib2 的错误,因为 httplib2 是一个非常古老且常见的库。

4

1 回答 1

7

不,连接未关闭的事实不是错误,有必要为下一个请求重用连接。

编写方式httplib2,它等待服务器关闭连接或超时,它不会主动关闭它们(错误除外)。如果连接已关闭,httplib2则下次使用时将尝试重新建立它。

关闭连接(就像您对源代码所做的那样)将使这成为不可能,每个请求都必须使用它自己的连接。

销毁httplib2.Http对象应该自动关闭打开的连接,因为它们只在它的connections字典中被引用,所以如果你不保留对Http你创建的对象的任何引用,它应该可以工作。你确定你没有任何参考资料吗?

或者,您可以将Connnection: close标头传递给您的请求:

http.request("http://example.org", headers={'Connection': 'close'})

这应该会导致服务器在每次请求后关闭连接。或者,您可以尝试手动关闭对象connections字典中的所有连接。

于 2013-05-22T09:58:32.753 回答