- 浏览: 651131 次
- 性别:
- 来自: 北京
-
文章分类
- 全部博客 (820)
- java开发 (110)
- 数据库 (56)
- javascript (30)
- 生活、哲理 (17)
- jquery (36)
- 杂谈 (15)
- linux (62)
- spring (52)
- kafka (11)
- http协议 (22)
- 架构 (18)
- ZooKeeper (18)
- eclipse (13)
- ngork (2)
- dubbo框架 (6)
- Mybatis (10)
- 缓存 (28)
- maven (20)
- MongoDB (3)
- 设计模式 (3)
- shiro (10)
- taokeeper (1)
- 锁和多线程 (3)
- Tomcat7集群 (12)
- Nginx (34)
- nodejs (1)
- MDC (1)
- Netty (7)
- solr (15)
- JSON (8)
- rabbitmq (32)
- disconf (7)
- PowerDesigne (0)
- Spring Boot (31)
- 日志系统 (6)
- erlang (2)
- Swagger (3)
- 测试工具 (3)
- docker (17)
- ELK (2)
- TCC分布式事务 (2)
- marathon (12)
- phpMyAdmin (12)
- git (3)
- Atomix (1)
- Calico (1)
- Lua (7)
- 泛解析 (2)
- OpenResty (2)
- spring mvc (19)
- 前端 (3)
- spring cloud (15)
- Netflix (1)
- zipkin (3)
- JVM 内存模型 (5)
- websocket (1)
- Eureka (4)
- apollo (2)
- idea (2)
- go (1)
- 业务 (0)
- idea开发工具 (1)
最新评论
-
sichunli_030:
对于频繁调用的话,建议采用连接池机制
配置TOMCAT及httpClient的keepalive以高效利用长连接 -
11想念99不见:
你好,我看不太懂。假如我的项目中会频繁调用rest接口,是要用 ...
配置TOMCAT及httpClient的keepalive以高效利用长连接
总所周知http1.1(http1.0不是标准,依服务器而定)是支持长连接的,长连接能够保证服务器和客户端的socket能够高效利用,减少握手等额外的开销。httpClient在正常情况下会带上Connection: keep-alive表示我是支持长连接的,当完成一个请求后,视情况决定是否关闭连接。
但是如果服务器端连接次数计数达到指定值时,则会在返回内容中添加Connection: close信息,表示该连接将被关闭。
这个时候该connection就失效了,客户端如果下次请求服务器的话,需要重新创建一个新的连接。但是有个问题,是否连接保持是由服务器端决定的,一旦连接超时导致connection close,服务器是不会专门通知客户端的,所以我们不能依赖Connection: close信息来决定是否关闭socket。我们先来看看tomcat对长连接的配置。下面是一个典型的配置长连接的方式:
其中:
keepAliveTimeout:表示在下次请求过来之前,tomcat保持该连接多久。这就是说假如客户端不断有请求过来,且为超过过期时间,则该连接将一直保持。
maxKeepAliveRequests:表示该连接最大支持的请求数。超过该请求数的连接也将被关闭(此时就会返回一个Connection: close头给客户端)。
由于keeplive的不确定性,这对客户端高效的实现http请求带来了一定挑战。在httpClient中对连接的复用采用了多种机制同时保证,但是这需要和服务器端一起配合。如果服务器端和客户端在keepAlive相关的配置不匹配的话,轻则效率低下,重则伤筋动骨,具体有哪些需要注意的地方?下面一一道来。
http连接池
httpClient提供了连接池实现连接的复用,这是实现高效请求的基础,下面是给httpClient设置连接池的方法:
有几个需要注意的地方:
1.如果你的客户端连接的目标服务器只有一个,那么大可设置最大route连接数和最大连接池连接数相同,以便高效利用连接池中创建的连接。
2.创建的httpClient对象是线程安全的,如果连接的目标服务器只有一个的话,创建一个全局对象即可。一个对象好比开了一个浏览器,多个线程无需每次请求时专门开一个浏览器,统一一个即可。
3.如果httpClient对象不再使用,记得关闭,释放与服务器保持连接的socket,以便服务器更高效的释放资源。
连接清理线程
虽然连接池有了,但是由于http连接的特殊性(只有在通讯正在进行(block)时才能够对IO事件做出反应)。一旦连接被放回连接池后,我们无从知道该连接是否还是keepalive的,且此时也无法监控当前socket的状态(即服务器主动关闭了连接,但客户端没有通讯时是不知道当前连接的状态是怎样的)。怎么办呢?httpClient采用了一个折中的方案来检查连接的“状态”,就是由客户端自己通过配置去主动关闭其认为是失效的连接。具体方法如下:
我们新建了一个Thread,该Thread每隔5s进行一次清理,把认为是expired或空闲超过30s的连接给关闭掉。这里关闭空闲的连接好理解。问题是关闭expired的连接,什么样的连接才算是expired呢?刚才说过客户端是无法检测到对应的连接是否是alive的,故通过一个配置告诉httpClient每个连接大概什么时候会断掉,httpClient会认为过了该时间的连接就是expired的连接。默认情况下,httpClient认为只要连接上服务器的socket将永远不会断掉。显然这种假设过于乐观。
keepalive策略
为了使connMgr.closeExpiredConnections();起到作用,我们需要指定连接keep alive策略,来告诉httpClient,哪些连接大概什么时候会过期,你可以关闭他们。下面是一个设置keep alive 策略的例子
这个例子指明在访问www.naughty-server.com和其他未知服务器时的keeplive为一个固定值,如果服务器返回keeplive过期时间,则通过服务器告诉客户端该连接大概什么时候过期(注意这不是一个标准的http协议,不是所有服务器都支持)。
总结
如果httpClient是访问单一的地址(如rpc请求),通过与服务器配置配合能够更高效的利用客户端的连接池,例如以tomcat为例,设置maxKeepAliveRequests为-1则可以使该连接可以请求无限次数,而设置keepAliveTimeout为一个较大的时间则可以让客户端更有效的利用连接池中的连接。凡事都有前提,如果目标tomcat即用于rpc调用,又用于服务正常连接请求的话,则上面优化反而会大量消耗服务器资源。这时可以讲这两类服务拆分成两个tomcat进行分别处理。另外,如果在服务器前面配有代理的话(apache,nginx),则还需视情况设置代理的keepAlive策略以提高利用率。
参考:http://backend.blog.163.com/blog/static/2022941262014029105618173/
http://www.programcreek.com/java-api-examples/index.php?api=org.apache.http.conn.ConnectionKeepAliveStrategy

但是如果服务器端连接次数计数达到指定值时,则会在返回内容中添加Connection: close信息,表示该连接将被关闭。

这个时候该connection就失效了,客户端如果下次请求服务器的话,需要重新创建一个新的连接。但是有个问题,是否连接保持是由服务器端决定的,一旦连接超时导致connection close,服务器是不会专门通知客户端的,所以我们不能依赖Connection: close信息来决定是否关闭socket。我们先来看看tomcat对长连接的配置。下面是一个典型的配置长连接的方式:

其中:
keepAliveTimeout:表示在下次请求过来之前,tomcat保持该连接多久。这就是说假如客户端不断有请求过来,且为超过过期时间,则该连接将一直保持。
maxKeepAliveRequests:表示该连接最大支持的请求数。超过该请求数的连接也将被关闭(此时就会返回一个Connection: close头给客户端)。
由于keeplive的不确定性,这对客户端高效的实现http请求带来了一定挑战。在httpClient中对连接的复用采用了多种机制同时保证,但是这需要和服务器端一起配合。如果服务器端和客户端在keepAlive相关的配置不匹配的话,轻则效率低下,重则伤筋动骨,具体有哪些需要注意的地方?下面一一道来。
http连接池
httpClient提供了连接池实现连接的复用,这是实现高效请求的基础,下面是给httpClient设置连接池的方法:
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); //连接池最大生成连接数200 cm.setMaxTotal(200); // 默认设置route最大连接数为20 cm.setDefaultMaxPerRoute(20); // 指定专门的route,设置最大连接数为80 HttpHost localhost = new HttpHost("locahost", 80); cm.setMaxPerRoute(new HttpRoute(localhost), 50); // 创建httpClient CloseableHttpClient httpClient = HttpClients.custom() .setConnectionManager(cm) .build();
有几个需要注意的地方:
1.如果你的客户端连接的目标服务器只有一个,那么大可设置最大route连接数和最大连接池连接数相同,以便高效利用连接池中创建的连接。
2.创建的httpClient对象是线程安全的,如果连接的目标服务器只有一个的话,创建一个全局对象即可。一个对象好比开了一个浏览器,多个线程无需每次请求时专门开一个浏览器,统一一个即可。
3.如果httpClient对象不再使用,记得关闭,释放与服务器保持连接的socket,以便服务器更高效的释放资源。
连接清理线程
虽然连接池有了,但是由于http连接的特殊性(只有在通讯正在进行(block)时才能够对IO事件做出反应)。一旦连接被放回连接池后,我们无从知道该连接是否还是keepalive的,且此时也无法监控当前socket的状态(即服务器主动关闭了连接,但客户端没有通讯时是不知道当前连接的状态是怎样的)。怎么办呢?httpClient采用了一个折中的方案来检查连接的“状态”,就是由客户端自己通过配置去主动关闭其认为是失效的连接。具体方法如下:
public static class IdleConnectionMonitorThread extends Thread { private final HttpClientConnectionManager connMgr; private volatile boolean shutdown; public IdleConnectionMonitorThread(HttpClientConnectionManager connMgr) { super(); this.connMgr = connMgr; } @Override public void run() { try { while (!shutdown) { synchronized (this) { wait(5000); // Close expired connections connMgr.closeExpiredConnections(); // Optionally, close connections // that have been idle longer than 30 sec connMgr.closeIdleConnections(30, TimeUnit.SECONDS); } } } catch (InterruptedException ex) { // terminate } } public void shutdown() { shutdown = true; synchronized (this) { notifyAll(); } } }
我们新建了一个Thread,该Thread每隔5s进行一次清理,把认为是expired或空闲超过30s的连接给关闭掉。这里关闭空闲的连接好理解。问题是关闭expired的连接,什么样的连接才算是expired呢?刚才说过客户端是无法检测到对应的连接是否是alive的,故通过一个配置告诉httpClient每个连接大概什么时候会断掉,httpClient会认为过了该时间的连接就是expired的连接。默认情况下,httpClient认为只要连接上服务器的socket将永远不会断掉。显然这种假设过于乐观。
keepalive策略
为了使connMgr.closeExpiredConnections();起到作用,我们需要指定连接keep alive策略,来告诉httpClient,哪些连接大概什么时候会过期,你可以关闭他们。下面是一个设置keep alive 策略的例子
ConnectionKeepAliveStrategy myStrategy = new ConnectionKeepAliveStrategy() { public long getKeepAliveDuration(HttpResponse response, HttpContext context) { // Honor 'keep-alive' header HeaderElementIterator it = new BasicHeaderElementIterator( response.headerIterator(HTTP.CONN_KEEP_ALIVE)); while (it.hasNext()) { HeaderElement he = it.nextElement(); String param = he.getName(); String value = he.getValue(); if (value != null && param.equalsIgnoreCase("timeout")) { try { return Long.parseLong(value) * 1000; } catch(NumberFormatException ignore) { } } } HttpHost target = (HttpHost) context.getAttribute( HttpClientContext.HTTP_TARGET_HOST); if ("www.naughty-server.com".equalsIgnoreCase(target.getHostName())) { // Keep alive for 5 seconds only return 5 * 1000; } else { // otherwise keep alive for 30 seconds return 30 * 1000; } } }; CloseableHttpClient client = HttpClients.custom() .setKeepAliveStrategy(myStrategy) .build();
这个例子指明在访问www.naughty-server.com和其他未知服务器时的keeplive为一个固定值,如果服务器返回keeplive过期时间,则通过服务器告诉客户端该连接大概什么时候过期(注意这不是一个标准的http协议,不是所有服务器都支持)。
总结
如果httpClient是访问单一的地址(如rpc请求),通过与服务器配置配合能够更高效的利用客户端的连接池,例如以tomcat为例,设置maxKeepAliveRequests为-1则可以使该连接可以请求无限次数,而设置keepAliveTimeout为一个较大的时间则可以让客户端更有效的利用连接池中的连接。凡事都有前提,如果目标tomcat即用于rpc调用,又用于服务正常连接请求的话,则上面优化反而会大量消耗服务器资源。这时可以讲这两类服务拆分成两个tomcat进行分别处理。另外,如果在服务器前面配有代理的话(apache,nginx),则还需视情况设置代理的keepAlive策略以提高利用率。
参考:http://backend.blog.163.com/blog/static/2022941262014029105618173/
http://www.programcreek.com/java-api-examples/index.php?api=org.apache.http.conn.ConnectionKeepAliveStrategy
评论
2 楼
sichunli_030
2017-05-23
对于频繁调用的话,建议采用连接池机制
1 楼
11想念99不见
2017-05-17
你好,我看不太懂。假如我的项目中会频繁调用rest接口,是要用连接池还是用长连接。
发表评论
-
stringentity、urlEncodeFormEntity区别
2018-04-10 20:43 783UrlEncodedFormEntity()的形式比较单一,只 ... -
HttpClient Post 二进制/字节流/byte[]
2018-03-11 23:29 1703http://blog.csdn.net/Sidyhe/art ... -
Socket端口状态说明 LISTENING、ESTABLISHED、TIME_WAIT及CLOSE_WAIT
2017-12-15 19:30 878http://blog.csdn.net/klzyf100/a ... -
java 实现https请求的基本原理与介绍
2017-09-17 23:13 705实现https请求的基本原理与介绍 http://blog.c ... -
wireshark过滤语法总结
2017-08-29 16:14 503wireshark过滤语法总结 http://blog.csd ... -
OkHttp3
2017-08-09 10:22 468http://www.jianshu.com/p/187328 ... -
HttpClient内部三个超时时间的区别
2017-07-22 15:21 18051.HttpClient内部三个超时 ... -
HttpClient 发送 HTTP、HTTPS 请求的简单封装
2017-05-27 11:27 641http://blog.csdn.net/happylee66 ... -
httpclient长链接与短链接
2017-05-27 10:12 1473http://blog.csdn.net/yaoqinggg/ ... -
正确使用ngrok穿透内网
2017-05-27 09:55 642http://blog.csdn.net/jiangbo_ph ... -
伪造Http请求IP地址
2017-05-25 20:18 2124注意:伪造Http请求IP地址一般为非推荐使用手段 一般使用 ... -
HTTP长连接和短连接以及推送技术原理
2017-03-05 22:39 1156http://blog.csdn.net/freewaywal ... -
HttpClient容易忽视的细节——连接关闭
2017-02-17 15:04 506HttpClient client = new HttpCli ... -
【HTTP】Fiddler(二) - 使用Fiddler做抓包分析
2017-02-17 08:24 613一.对PC(笔记本)参数进行配置 1. 配置fiddler允许 ... -
fiddler2抓包工具使用图文教程
2016-09-29 16:51 474参考:http://blog.163.com/hlz_2599 ... -
chrome安装插件,安装Postman
2016-09-29 08:56 6941、下载postman插件,可以自己到网上下载,也可以点击ht ... -
tcp三次握手建立连接,四次握手关闭连接
2016-09-12 09:05 50在发送http请求之前,客户端和服务器必须建立tcp三次握手连 ... -
RequestConfig类解析
2016-08-27 17:55 2228这个类位于 org.apache.http.client.co ... -
http的安全方法和幂等性
2016-07-26 14:58 744最近在研究http,看到htt ... -
TCP的三次握手(建立连接)和四次挥手(关闭连接)
2016-05-15 13:01 498http://www.cnblogs.com/Jessy/p/ ...
相关推荐
在这个“springboot-keepalive设置测试”项目中,我们将关注的是如何在Spring Boot应用中配置和测试HTTP长连接(keepalive)功能,以优化服务器与客户端之间的通信效率。 HTTP长连接,也被称为持久连接,允许TCP...
该资源为joblib-1.1.0-py2.py3-none-any.whl,欢迎下载使用哦!
内容概要:本文详细介绍了如何使用MATLAB/Simulink R2015b搭建Buck-Boost变换器的开环和闭环控制仿真模型。首先,作者解释了Buck-Boost变换器的基本构成及其在电源设计中的重要性。接着,逐步指导读者构建开环模型,包括设置关键参数如PWM频率、占空比、输入电压等,并展示了开环控制下的输出特性。随后,引入了PID控制器进行闭环控制,强调了PID参数的选择与调整方法,以及如何通过增加电压采样和误差比较来提高系统的稳定性。此外,还分享了一些常见的仿真错误及解决方案,如电感值选取不当、二极管模型过于理想等问题。最后,提供了几个有趣的实验案例,如动态改变占空比、突变负载等,以展示闭环控制的优势。 适合人群:具有一定电力电子和MATLAB/Simulink基础的技术人员或学生。 使用场景及目标:适用于希望深入理解Buck-Boost变换器工作原理及其控制策略的研究者和技术爱好者。通过动手实践,掌握开环与闭环控制的区别,学会优化PID参数,提升电源设计能力。 其他说明:文中附有多处代码片段和实用技巧,有助于读者更好地理解和应用所学知识。同时提醒读者注意不同MATLAB版本间的兼容性问题。
2023年上海市高等学校计算机等级考试.docx
能检测死锁,输出相关代码便于排查
电子商务物流业务管理教材.pptx
基于stm32的控制底层
2023年全国计算机等级考试三级数据库试题.doc
2023年计算机二级考试操作题真题.doc
2023年自考管理系统中计算机应用试题及答案.doc
资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。
2023年电子科技秋网与网站设计在线作业.doc
内容概要:本文详细介绍了基于脉振高频电压注入的无速度传感器控制系统。该方法通过向电机定子绕组注入高频电压信号(如2kHz),利用高频响应电流中的转子位置信息进行实时定位。文中展示了具体的代码实现,包括信号注入、带通滤波、正交锁相环以及位置跟踪观测器的设计。此外,讨论了参数整定、抗干扰措施(如伪随机频移键控)和实际调试过程中遇到的问题及其解决方案。该方法适用于低速或零速情况,能够显著提高位置估计的准确性。 适合人群:从事电机控制、自动化控制领域的工程师和技术研究人员。 使用场景及目标:①用于工业伺服系统中,特别是那些对成本敏感或安装空间有限的应用;②解决传统方法在低速或零速情况下无法准确估计转子位置的问题;③提供一种可靠的无速度传感器控制方案,减少硬件成本和维护难度。 其他说明:该方法虽然在低速时表现出色,但在高速时精度有所下降,可以通过混合观测策略进行优化。同时,实际应用中需要注意高频信号带来的额外损耗和参数敏感性问题。
2023年计算机二级基础知识重点总结.docx
该资源为joblib-1.1.0.tar.gz,欢迎下载使用哦!
An-225大型运输机实体装配模型由225个实体零件基元组成,分为21个子装配模块。 该模型是通过缩放一个基本的8.5英寸x11英寸三视图原理图而开发的。 因此,其精度有所降低。
matlab
2024年大数据软件项目深度研究分析报告.docx
2023年四川省一级计算机等级考试训练题.doc
矢量边界,行政区域边界,精确到乡镇街道,可直接导入arcgis使用