如何通过httpclient在Java中设置TCP Keep Alive [英] How to set TCP keep Alive in java from httpclient

查看:2034
本文介绍了如何通过httpclient在Java中设置TCP Keep Alive的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我位于AWS私有子网中的Java应用程序通过AWS Nat网关连接到http服务器.我正在通过httpclient调用POST请求到HTTP服务器.该请求将花费10多分钟才能完成.我已将套接字超时和连接超时配置为1小时,因为这是后台任务.但是中间的AWS NAT网关将在300秒(5分钟)后发送回RST数据包并导致连接重置,因此我无法增加NAT网关超时.所以我需要从我的应用程序端处理问题.

My java application which resides in AWS private subnet connects to an http server via AWS Nat gateway. I am calling a POST request via httpclient to the HTTP server. That request will take more than 10 minutes to complete. I have configured a socket time out and connection timeout of 1 hour as this this a background task . But the intermediate AWS NAT gateway will send back a RST packet after 300 secs [5 mins] and cause the connection to get resetted , there is no way i can increase the NAT gateway timeout. So i need to handle the problem from my application side.

我的策略是使用tcp保持活动时间,它将每240秒发送一次数据包以保持连接活动.我已经配置了 如下

My strategy is to use a tcp keep alive time which will send a packet say every 240 secs to keep the connection active. I have configured this as below

CloseableHttpClient httpClient = HttpClients.createDefault()
HttpParams params = httpClient.getParams();
HttpConnectionParams.setConnectionTimeout(params, 3600000); //connection Timeout
HttpConnectionParams.setSoTimeout(params, 3600000); // Socket Time out
HttpConnectionParams.setSoKeepalive(params, true); //Enable Socket level keep alive time

,然后通过execute方法

and then call the post request via execute method

HttpPost post = new HttpPost("http://url");
HttpResponse response = httpClient.execute(post);

由于我使用的是Linux系统,因此我已为服务器配置了以下Sysctl值

Since i am using a linux system i have configured the server with following Sysctl values

sysctl -w net.ipv4.tcp_keepalive_time=240 
sysctl -w net.ipv4.tcp_keepalive_intvl=240
sysctl -w net.ipv4.tcp_keepalive_probes=10

但是在执行程序时,未启用保持活动状态,并且连接失败.

But while executing the program the keep alive is not enabled and connection fails as previous.

我已经使用netstat -o选项进行了检查,如下所示,保持活动状态已关闭

I have checked this with netstat -o option and as shown below keep alive is off

tcp        0      0 192.168.1.141:43770     public_ip:80          ESTABLISHED 18134/java           off (0.00/0/0)

有什么办法可以使用httpclient设置TCP从Java代码保持有效.我也可以看到不推荐使用HttpConnectionParams.但是我找不到任何可以设置保持活动状态的新类

Is there any way i can set TCP keep alive from java code using httpclient . Also i can see HttpConnectionParams are deprecated. But I couldnt find any new class which can set keep alive

谢谢

推荐答案

我找到了解决该问题的方法.奇怪的情况是,我无法在httpclient中使用一些构建器类来传递套接字保持活动状态.我在问题中指定的一种方法是使用HttpConnectionParams,如下所示,但这不起作用,并且现在不推荐使用此类.

I have found a solution to the problem . Curious case is there is no way i can use some builder class in httpclient to pass socket keep alive . One method as i specified in the question is using HttpConnectionParams as below but this is not working and this class is now deprecated.

HttpParams params = httpClient.getParams();
HttpConnectionParams.setSoKeepalive(params, true);

因此,在检查apache http文档时,我可以看到现在连接参数已通过RequestConfig类传递给httpclient.此类的构建器提供了用于设置connection_time_out和socket_time_out的解决方案.但是检查此代码,我看不到启用SocketKeepAlive的选项.因此,唯一的解决方案是使用SocketBuilder类直接创建一个Socket,并将其传递给HttpClientBuilder.

So while checking apache http docs I can see that now connection parameters are passed to httpclient via RequestConfig class . Builders of this class provide solution to set connection_time_out and socket_time_out. But checking the socurce code of this I couldnt see an option to enable SocketKeepAlive which is what we want. So the only solution is directly creating a Socket using SocketBuilder class and pass that to the HttpClientBuilder.

以下是工作代码

SocketConfig socketConfig = SocketConfig.custom().setSoKeepAlive(true).setSoTimeout(3600000).build(); //We need to set socket keep alive
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(3600000).build();
        CloseableHttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).
                                           setDefaultSocketConfig(socketConfig).build();
HttpPost post = new HttpPost(url.toString());
HttpResponse response = httpClient.execute(post);

在执行上述操作时,我可以根据我在Linux内核中设置的sysctl值,在套接字中正确设置了保持活动状态

While executing above i can see that keep alive is properly set in the socket based on the sysctl values i set in linux kernel

tcp        0      0 localip:48314     public_ip:443     ESTABLISHED 14863/java          keepalive (234.11/0/0)

如果有人有更好的解决方案可以从Requestconfig类或任何其他高级构建器类启用Socket Keep alive,我可以提出建议.

If some one has a better solution to enable Socket Keep alive from Requestconfig class or any other high level builder class i am open to suggestions.

这篇关于如何通过httpclient在Java中设置TCP Keep Alive的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆