HttpClient连接池,发现对于高并发的请求,效率提升很大。虽然知道是因为建立了长连接,导致请求效率提升,但是对于内部的原理还是不太清楚。后来在网上看到了HTTP协议的发展史,里面提到了一个属性Connection:keep-alive,引起了我极大的兴趣,觉得两者之间必然存在联系,果真当我查阅了一些资料之后,发现了HttpClient连接池连接保持、超时和失效的机制。

为什么要用Http连接池

1、降低延迟:如果不采用连接池,每次连接发起Http请求的时候都会重新建立TCP连接(经历3次握手),用完就会关闭连接(4次挥手),如果采用连接池则减少了这部分时间损耗,别小看这几次握手,本人经过测试发现,基本上3倍的时间延迟

2、支持更大的并发:如果不采用连接池,每次连接都会打开一个端口,在大并发的情况下系统的端口资源很快就会被用完,导致无法建立新的连接

 

1、保持实现原理

要想保持连接,首先客户端需要告诉服务器希望保持长连接,这就是所谓的Keep-Alive模式(又称持久连接,连接重用),HTTP1.0中默认是关闭的,需要在HTTP头加入"Connection: Keep-Alive",才能启用Keep-Alive;HTTP1.1中默认启用Keep-Alive,加入"Connection: close ",才关闭。

但客户端设置了Keep-Alive并不能保证连接就可以保持,这里情况比较复杂。要想在一个TCP上进行多次的HTTP会话,关键是如何判断一次HTTP会话结束了?非Keep-Alive模式下可以使用EOF(-1)来判断,但Keep-Alive时服务器不会自动断开连接,有两种最常见的方式。

使用Conent-Length(HTTP协议)

顾名思义,Conent-Length表示实体内容长度,客户端(服务器)可以根据这个值来判断数据是否接收完成。当请求的资源是静态的页面或图片,服务器很容易知道内容的大小,但如果遇到动态的内容,或者文件太大想多次发送怎么办?

使用Transfer-Encoding(HTTP协议)

当需要一边产生数据,一边发给客户端,服务器就需要使用 Transfer-Encoding: chunked 这样的方式来代替 Content-Length,Chunk编码将数据分成一块一块的发送。它由若干个Chunk串连而成,以一个标明长度为0 的chunk标示结束。每个Chunk分为头部和正文两部分,头部内容指定正文的字符总数(十六进制的数字 )和数量单位(一般不写),正文部分就是指定长度的实际内容,两部分之间用回车换行(CRLF) 隔开。在最后一个长度为0的Chunk中的内容是称为footer的内容,是一些附加的Header信息。

总结下HttpClient如何判断连接是否保持:

  1. 检查返回response报文头的Transfer-Encoding字段,若该字段值存在且不为chunked,则连接不保持,直接关闭。
  2. 检查返回的response报文头的Content-Length字段,若该字段值为空或者格式不正确(多个长度,值不是整数),则连接不保持,直接关闭。
  3. 检查返回的response报文头的Connection字段(若该字段不存在,则为Proxy-Connection字段)值:
    • 如果这俩字段都不存在,则1.1版本默认为保持, 1.0版本默认为连接不保持,直接关闭。
    • 如果字段存在,若字段值为close 则连接不保持,直接关闭;若字段值为keep-alive则连接标记为保持。

2、 保持连接时间

保持时间计时开始时间为连接交换至连接池的时间。 保持时长计算规则为:获取response中 Keep-Alive字段中timeout值,若该存在,则保持时间为 timeout值*1000,单位毫秒。若不存在,则连接保持时间设置为-1,表示为无穷。

3、保持过程中如何保证连接没有失效?

很难保证。传统阻塞I/O模型,只有当I/O操作的时候,socket才能响应I/O事件。当TCP连接交给连接管理器后,它可能还处于“保持连接”的状态,但是无法监听socket状态和响应I/O事件。如果这时服务器将连接关闭的话,客户端是没法知道这个状态变化的,从而也无法采取适当的手段来关闭连接。

针对这种情况,HttpClient采取一个策略,通过一个后台的监控线程定时的去检查连接池中连接是否还“新鲜”,如果过期了,或者空闲了一定时间则就将其从连接池里删除掉。ClientConnectionManager提供了 closeExpiredConnections和closeIdleConnections两个方法

HttpClient连接池的更多相关文章

  1. Http持久连接与HttpClient连接池

    一.背景 HTTP协议是无状态的协议,即每一次请求都是互相独立的.因此它的最初实现是,每一个http请求都会打开一个tcp socket连接,当交互完毕后会关闭这个连接. HTTP协议是全双工的协议, ...

  2. Http 持久连接与 HttpClient 连接池

    一.背景 HTTP协议是无状态的协议,即每一次请求都是互相独立的.因此它的最初实现是,每一个http请求都会打开一个tcp socket连接,当交互完毕后会关闭这个连接. HTTP协议是全双工的协议, ...

  3. HttpClient连接池的一些思考

    前言 使用apache的httpclient进行http的交互处理已经很长时间了,而httpclient实例则使用了http连接池,想必大家也没有关心过连接池的管理.事实上,通过分析httpclien ...

  4. HttpClient实战三:Spring整合HttpClient连接池

    简介 在微服务架构或者REST API项目中,使用Spring管理Bean是很常见的,在项目中HttpClient使用的一种最常见方式就是:使用Spring容器XML配置方式代替Java编码方式进行H ...

  5. httpclient连接池在ES Restful API请求中的应用

    package com.wm.utils; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http ...

  6. springboot使用RestTemplate+httpclient连接池发送http消息

    简介 RestTemplate是spring支持的一个请求http rest服务的模板对象,性质上有点像jdbcTemplate RestTemplate底层还是使用的httpclient(org.a ...

  7. 使用HttpClient连接池进行https单双向验证

    https单双向验证环境的搭建参见:http://www.cnblogs.com/YDDMAX/p/5368404.html 一.单向握手 示例程序: package com.ydd.study.he ...

  8. HttpClient连接池的连接保持、超时和失效机制

    HTTP是一种无连接的事务协议,底层使用的还是TCP,连接池复用的就是TCP连接,目的就是在一个TCP连接上进行多次的HTTP请求从而提高性能.每次HTTP请求结束的时候,HttpClient会判断连 ...

  9. HttpClient连接池抛出大量ConnectionPoolTimeoutException: Timeout waiting for connection异常排查

    转自: http://blog.csdn.net/shootyou/article/details/6615051 今天解决了一个HttpClient的异常,汗啊,一个HttpClient使用稍有不慎 ...

随机推荐

  1. ssh的配置,ssh打开密钥登陆,关闭密码登陆。

    刚装玩fedora,那么我们就以fedora为例来说一下怎么配置: 1.先确认是否已安装ssh服务: [root@localhost ~]# rpm -qa | grep openssh-server ...

  2. dnspod 动态域名的使用。openwrt使用dnspod动态域名解析。

    这里主要说的是linux shell下的使用. 先看接口说明: 接口地址: https://dnsapi.cn/Record.Ddns HTTP请求方式: POST 请求参数: 公共参数 domain ...

  3. MyEclipse关联SVN下载项目到本地

    目的:在MyEclipse上关联SVN,从SVN服务器上,下载项目,到本机的MyEclipse上,并运行 准备工作 1.安装好Tomcat和MyEclipse 2.安装好Plsql,并配置连接好Ora ...

  4. 使用word2013写博客

    额额  要使用的话首先要配置一下: 选择word2013的创建,然后点击模版,搜索博客. 然后就是创建账户了,账户主要填写的下面这些信息: 注意,cnblogs后面的子域名应该使用你自己的子域名 下面 ...

  5. Apache和iis的冲突处理

    http://wenku.baidu.com/link?url=N4GYFpkQyr8G0kVEy3AR2Q5FBho8EOle-_5inEfEq6QSxlyzB3xSbcpeugRdExkSU-tw ...

  6. OK335xS CAN device register and deiver match hacking

    /************************************************************************* * OK335xS CAN device regi ...

  7. led不同颜色的驱动电压和驱动电流

    LED耗电非常低,一般来说LED的工作电压是2-3.6V,其中红光电压是1.8-2.1V 波长610-620    绿光电压是3.0-3.5V 波长520-530   兰光电压是3.0-3.5V 波长 ...

  8. Android Studio安装、配置教程全 - 安卓开发环境的配置手册

    Android Studio的安装.配置 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 一 Downloa ...

  9. 【JVM】jvm至jstack命令

    一.介绍 jstack是java虚拟机自带的一种堆栈跟踪工具.jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项&qu ...

  10. sublime 自动添加兼容前缀插件autoprefixer

    安装插件autoprefixer步骤: 1.确保Node.js已经安装,未安装请 点击 这里>> 2.下载autoprefixer插件 https://github.com/sindres ...