应用使能TCP keepalive实现链路保活的方放
背景:
当前仍然有少量WEB基于同步HTTP请求/响应 的方式做长事务处理,导致后台服务器处理超长时间(比如5分钟)没有任何报文响应,最终连接被中间的网络设备老化掉连接而中断业务. 这个常见于NAT网络或者LVS负载均衡场景.
解决思路:
对于这类问题可以使能TCP的keepalive机制,在链路空载时发心跳包保活.
心跳保活有2种,一种是客户端发起,一种的服务端发起. 考虑到性能,应用对接一般由客户端发起,服务端响应, web场景面向众多客户端时,客户端发起实施困难,这个时候选用服务端发起.
系统有默认的TCP keepalive参数,可以设置 空载心跳保活的时长,间隔,次数, 属于系统级别的默认参数,每次启动都需要设置.
相关参数的命令行设置方法:
#心跳保活时长(最长空载时间) sysctl -w net.ipv4.tcp_keepalive_time=15 #保活时心跳包发送次数(收不到对方响应时的重发次数) sysctl -w net.ipv4.tcp_keepalive_probes=2 #保活时每次发包间隔 sysctl -w net.ipv4.tcp_keepalive_intvl=3
具体应用需要创建socket时使能keepalive才会真正生效. 不同应用的配置方式有差别.
具体应用的开启参考:
1\Tomcat服务端
在具体的Connector设置socket参数,默认的protocol可能不支持,需要修改
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
改成
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" socket.soKeepAlive="true" connectionTimeout="20000" redirectPort="8443" />
重启即可
其他参数连接:http://tomcat.apache.org/tomcat-7.0-doc/config/http.html#NIO_specific_configuration
2\Java httpclient-xxx.jar
public class HttpTest { public static void main(String[] args) throws Exception{ BasicHttpClientConnectionManager basicConnManager = new BasicHttpClientConnectionManager(); //这里开启keepalive basicConnManager.setSocketConfig(SocketConfig.custom().setSoKeepAlive(true).build()); HttpClientContext context = HttpClientContext.create(); CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(basicConnManager).build(); HttpGet httpget = new HttpGet("http://localhost:8080/"); System.out.println("sending http get"); final CloseableHttpResponse resp = httpClient.execute(httpget, context); String respStr = EntityUtils.toString(resp.getEntity()); Thread.sleep(TimeUnit.MINUTES.toMillis(2)); System.out.println(respStr); } }
其他相关组件的设置参考:
https://blog.csdn.net/nimasike/article/details/81144592
上述方法仅demo演示,具体应用场景需要根据需要选中其他合适的配置,避免参数冲突.
- 点赞
- 收藏
- 关注作者
评论(0)