【问题标题】:should connectionmanager really do the shutdown?connectionmanager 真的应该关闭吗?
【发布时间】:2011-12-13 13:55:58
【问题描述】:

有时我会收到

java.net.SocketException: Too many open files 
java.net.Socket.createImpl(Socket.java:397) 
java.net.Socket.connect(Socket.java:527) 
org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:123) 
org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:123) 
org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:147) 
org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:108) 
org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:415) 
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641) 
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:597) 

我看到了类似的问题java.net.SocketException: Too many open files,我也使用了apache的httpclient,但似乎答案对我没有太大帮助......

有两个答案:

1) 做httpClient.getConnectionManager().shutdown();

2) 调用entity.getContent().close() 而不是entity.consumeContent()

但似乎没有一个适合...

1) 问题是我使用的是ThreadSafeConnectionManager。它被创建一次(在应用程序启动时)。因此我们不会关闭(以便连接可重用)。如果我在此管理器上关闭 - 所有连接都将关闭。如果我使用SingleClientConnectionManager 是合适的,但我没有。我说的对吗?

2) 我发现我也没有关闭流。但是当我开始调试时 - 似乎这个getContent() 流已经关闭,甚至在调用consumeContent() 之前。尽管(即使在consumeContent 之后)那些 getContent() 流中的socketInputStream 以及套接字都没有关闭。不好吗?这可能是问题的原因吗?而且我没有找到关闭此套接字的方法!它位于外部输入流内部,所以我无法得到它。但是我在调​​试模式下看到这个socket没有关闭,还有SocketInputStream

我们应该如何正常使用ThreadSafeConnectionManager - 它应该只创建一次吗?如果是这样,如果有的话,如何正确关闭这些套接字?

【问题讨论】:

    标签: java sockets connection-pooling apache-httpclient-4.x


    【解决方案1】:

    如果我关闭此管理器 - 所有连接都将关闭。 如果我使用 SingleClientConnectionManager 将是合适的,但我 不。我说的对吗?

    每个不同的 HTTP 服务应该只使用一个连接管理器实例。您实际上并不需要将其关闭,但您可能希望从池中逐出空闲时间超过给定时间段的连接,如下所述:

    http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e659

    虽然(即使在consumeContent之后)里面的socketInputStream 那些 getContent() 流没有关闭,还有套接字。是吗 不好?

    不,不是。如果底层连接处于一致状态,它可能仍然保持活动状态。但是,必须关闭内容流,以确保将该连接释放回连接管理器。

    我们应该如何正常使用 ThreadSafeConnectionManager - 它应该只创建一次吗?如果是这样,如何正确关闭 那些插座(如果有的话)?

    是的,它应该只创建一次。但是,您必须通过关闭响应内容流来确保将连接正确释放回管理器。您可能还希望在一段时间不活动后主动从池中逐出连接。

    最后,请注意您的应用程序的其他组件也可能泄漏文件描述符。罪魁祸首不一定是HttpClient的连接管理器。

    【讨论】:

    • 哪些其他组件可能会泄漏文件描述符,例如?谢谢你的回答..
    • 几乎所有需要打开文件或套接字的东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-05
    • 2011-09-01
    • 2023-01-06
    • 2011-07-07
    • 2015-12-29
    • 2023-03-14
    相关资源
    最近更新 更多