《HttpClient容易忽视的细节——连接关闭》

http://blog.sina.com.cn/s/blog_3cdcd4a90100j0xf.html
老外有一篇文章,很好的描述了类似代码的性能隐患:《HttpClient容易忽视的细节——连接关闭》
1、英文原文:http://www.codeweblog.com/httpclient-s-easy-to-overlook-the-details-the-connection-is-closed/
2、中文翻译:http://www.javaeye.com/topic/234759

总述:实现一个HTTP接口不是件困难的事情,但是如何让这样的HTTP接口在高压力下(短时间内大数据量)也有稳定良好的表现,则不仅仅是HTTP服务器端需要做好设计与优化,而且HTTP客户端方面也同样需要非常谨慎与注意一些代码细节。否则,很有可能因(双方或单方)代码或配置中存在性能隐患,在软硬件环境的配合下就会出现一些“灵异”故障。

【HTTP协议知识】
为便于读者理解后文,先简述一些与HTTP性能密切相关的、又常常被工程师们所不深究的HTTP协议基础知识。

一、什么是HTTP KeepAlive
HTTP KeepAlive是就是通常所称的长连接。KeepAlive即服务器端为同一客户端保持连接一段时间(不立即关闭),以便于更多来自于此客户端的后续请求不断的利用此连接直至连接超时。
在HTTP1.0和HTTP1.1协议中都有对KeepAlive的支持。其中HTTP1.0需要在request header中增加”Connection: keep-alive“ 才能够支持,而HTTP1.1默认支持。

KeepAlive的更多阐述:
1、next request是在完成before request的response被client接收的情况下才发出。因此需要在向client写完before request的response后才能触发。
2、HTTP协议是基于TCP协议的,故服务器端与客户端都有可能关闭连接。KeepAlive只是表明了服务器端面对连接的一种优化策略,而客户端也完全可以主动关闭之(不利用)。

二、KeepAlive的好处与坏处
KeepAlive带来的好处是可以减少HTTP连接的开销,提高性能。比如,同一页面中如有很多内嵌的图片、JS、CSS等请求,则可以利用此特新性,使用少量的连接数(IE下一般是2个)更快的下载下来,使得网页更快的展示出来。

KeepAlive的坏处是:
如果有大量不同的客户端同时(或瞬间)请求服务器端,且每一个客户端的都长期占用连接(比如:不关闭 且ConnectionTimeOut设置过长)或服务器端也不快速失效连接(KeepAliveTimeout参数设置过大)的话,可能会快速占满服务 器连接资源,导致更多的请求被排队或被拒绝或服务器down掉。

总结:浏览器作为一种HTTP客户端,充分的、很好的利用了HTTP协议的KeepAlive,让我 们的浏览更加快速;而我们自写的HTTP客户端程序在KeepAlive特性(服务器已开启)下,需要以高数据量访问一个HTTP接口的时候,每一次请求 应当尽快关闭连接释放资源(重点推荐)或者在同一连接上适当多发几次请求(不推荐)。

【高性能HTTP应用的策略】
所以,当我们需要一个高性能的HTTP接口型应用时:
1、服务器端:关闭KeepAlive。
2、服务器端:最好直接支持HTTP协议(注意用POST,不要GET),而不是任何包装过的协议,比如:hessian/soap等。
3、服务器端:在一个请求中,最好设计成:支持多条指令批处理,以节省连接数。
4、服务器端:对请求的处理应当尽可能的快(如在150ms内)。
5、客户端:在代码中,同一个客户端实例中全部请求结束后应主动关闭连接(无须事先设置客户端的ConnectionTimeOut参数)。
6、客户端:如服务器未关闭KeepAlive,在同一个客户端实例中可以适量发出多个请求(总时间应稍小于服务器KeepAliveTimeout参数)。此方式需要精确操作,不推荐。
最后,在接口设计上,对于一些异步操作,尽量不要设计成单方面轮询模式(减少大量无谓请求数),应设计成被调用方的异步结果回调模式。

【一些优化细节】
在服务器端,我们一般选用的是Apache+Tomcat/JBoss的组合。关于JBoss的配置及优化可参看JBoss官网。
最主要的是关于Apache的优化,推荐阅读两篇文章:
1、Apache性能优化:http://www.aliwo.net:8080/2009/12/apache/
2、Apache中KeepAlive配置的合理使用:http://www.net527.cn/a/caozuoxitong/Linux/5283.html

在客户端的Java代码中,我们最常使用的是HttpClient工具包。
有一些细节要注意:
1、在每一个HttpClient实例发完请求后,(如不再使用)应及时关闭连接。
最简单的方式是,在HTTP Request Header中发送(Connection: close),指示服务器关闭当前连接。
代码如下:
method.setRequestHeader(“Connection”, “close”);
2、可以设计为单例模式:无需每次创建HttpClient实例,可多次发送请求(请求头设置见第一条)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
HttpClient是一个非常流行的Java库,用于发送HTTP请求和接收HTTP响应。在HttpClient中,可以使用短链接或长连接来与服务器进行通信。 短链接是指每次发送请求时都会创建一个新的连接,并在请求完成后关闭连接。这种方式适用于只需要发送少量请求的场景,每次请求都需要重新建立连接,无需维护连接状态。 长连接是指在发送请求后保持连接打开,并可以发送多个请求和接收多个响应。这样可以减少每次通信的开销,提高性能。长连接适用于需要频繁发送请求或保持与服务器的持续通信的场景。 在HttpClient中,默认情况下是使用短链接的。如果需要使用长连接,可以通过配置HttpClient连接管理器来实现。一种常见的方式是使用连接池来管理连接,可以重复利用已经建立的连接,减少连接的创建和销毁开销。 以下是使用HttpClient进行短链接和长连接的示例代码: 1. 短链接: ```java CloseableHttpClient httpClient = HttpClients.createDefault(); HttpGet httpGet = new HttpGet("http://example.com/api"); CloseableHttpResponse response = httpClient.execute(httpGet); // 处理响应 response.close(); httpClient.close(); ``` 2. 长连接: ```java PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); connManager.setMaxTotal(100); // 设置最大连接数 connManager.setDefaultMaxPerRoute(20); // 设置每个路由的最大连接HttpClient httpClient = HttpClients.custom() .setConnectionManager(connManager) .build(); HttpGet httpGet1 = new HttpGet("http://example.com/api/1"); CloseableHttpResponse response1 = httpClient.execute(httpGet1); // 处理响应 response1.close(); HttpGet httpGet2 = new HttpGet("http://example.com/api/2"); CloseableHttpResponse response2 = httpClient.execute(httpGet2); // 处理响应 response2.close(); // 不需要显式关闭HttpClient连接管理器会自动管理连接关闭 ``` 希望这些信息能对你有所帮助!如果你还有其他问题,请继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值