最近北京的系统又出问题了,检查了一下故障现象,发现又大量的HttpClient 发起的Http连接没有关闭,或者出于TIME_WAIT的状态。
于是查了一下HttpClient的代码,发现代码中用的post.releaseConnection() 来关闭连接的。这中关闭连接的方法是官方推荐的, 但是这种方法却有一定的缺陷:
原来releaseConnection方法,并不是立刻关闭Http连接,而是把它暂时放入空闲连接池中,等待Http连接超时后,才会关闭。在这期间,如果又有Http请求,可能会重用这个连接。这样做的好处是可以在一定程度上提高效率,但是缺点是连接不能立刻关闭。
关于这个问题,网上有解决方案了,一般有三种,简单点,在releaseConnection()后面调用一下httpclient.getHttpConnectionManager().closeIdleConnections(0); 就可以了
不过这只是第一步,因为调用了这个方法后,连接是被关闭了,但是,由于TCP协议的特点,这个连接会被改成TIME_WAIT状态,还需要经过一段时间后才会被操作系统回收。具体多长时间,是由操作系统的参数确定的。为了缩短TCP连接回收的时间,在Linux操作系统中,可以采用以下方法,修改配置参数:
vi /etc/sysctl
增加或修改net.ipv4.tcp_tw值:
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
利用这两个参数,可以允许系统重用TIME_WAIT状态的TCP连接,并缩短回收时间。这两个方法配合,基本上可以解决HTTP连接关闭不及时的问题