关于 HTTP 长连接
使用长连接能够减少建立销毁连接的消耗,三次握手、四次挥手对性能影响是很大的。一般 RPC 如 Dubbo 默认都是长连接的,HTTP 1.1 之上也可以支持长连接了,HTTP 2.0 也支持了单一长连接的多路复用。
一般 HTTP 服务前面都会挂 nginx 做负载均衡,那么长连接的设置也分为从客户端到 nginx、从 nginx 到服务端两部分。
如果使用 Java 的 apache HTTPClient 可以通过设置 ConnectionKeepAliveStrategy 和协议为 HTTP1.1 来使用长连接,对于 4.2.x 版本设置方法如下所示:
private static final ConnectionKeepAliveStrategy KEEP_ALIVE_STRATEGY = new ConnectionKeepAliveStrategy() {public long getKeepAliveDuration(HttpResponse response, HttpContext context) {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 {// 如果 response header 里有 Keep-Alive:timeout 参数,则使用其值作为长连接超时时间return Long.parseLong(value) * 1000;} catch (NumberFormatException ignore) {}}}return 30 * 1000; // 30s}};HttpParams params = new BasicHttpParams();// 指定使用 http1.1,1.1里默认使用长连接HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); SchemeRegistry registry = new SchemeRegistry();registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));//创建连接池PoolingClientConnectionManager cm = new PoolingClientConnectionManager(registry, 1, TimeUnit.MINUTES);cm.setDefaultMaxPerRoute(10);cm.setMaxTotal(200);httpClient = new DefaultHttpClient(cm, params);// 设置超时时间httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 100);httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 100);httpClient.getParams().setParameter(ClientPNames.CONN_MANAGER_TIMEOUT, 100);httpClient.setKeepAliveStrategy(KEEP_ALIVE_STRATEGY);
在 NGINX 请求后端服务时启用长连接需要配置:
proxy_http_version 1.1;
proxy_set_header Connection "";
keepalive_timeout 120s 120s;
keepalive_requests 10000;
关于长连接,有两个参数需要注意:
- keepalive_timeout:连接不活跃多长时间后断开,如果服务端(nginx)设置的时间比客户端短的话,可能会导致客户端请求异常。前提是 HTTPClient 都 http.connection.stalecheck 参数置为 false,也就是不在请求前检查连接的有效性。
- keepalive_requests:用于设置一个keep-alive连接上可以服务的请求的最大数量。当最大请求数量达到时,连接被关闭。nginx 和 Tomcat 上默认都是100,对于 QPS 较高的应用来说 100 有些太小了。
以上两个参数在 nginx、服务端都有,当 QPS 比较高时就需要做适当调整以减少或避免连接都频繁断开、建立。如果服务端使用的 Tomcat 容器,可以在 server.xml 文件里修改配置。
在 Spring Boot 2.x 里修改长连接的配置方法如下所示:
@Configuration
public class TomcatCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {@Overridepublic void customize(TomcatServletWebServerFactory factory) {factory.addConnectorCustomizers(connector -> {AbstractHttp11Protocol protocol = (AbstractHttp11Protocol) connector.getProtocolHandler();protocol.setMaxKeepAliveRequests(10000);protocol.setKeepAliveTimeout(60000); // 长连接超时时间,单位 ms});}
}
上面提到 HTTPClient 的 http.connection.stalecheck 参数用于设置是否在发送请求之前检查连接有效性,如果每次发请求都检查对性能影响也会较大,可以去掉该参数。但是去掉之后,在连接被 NGINX 关闭后依然发请求则会导致 NoHttpResponseException 异常,需要对其进行特殊处理,进行适当的重试。
资料
- nginx 优化
关于 HTTP 长连接相关推荐
- php 长连接心跳_支持gRPC长链接,深度解读Nacos2.0架构设计及新模型
作者 | 杨翊(席翁) Nacos PMC 来源|阿里巴巴云原生公众号 Nacos 简介 Nacos 在阿里巴巴起源于 2008 年五彩石项目,该项目完成了微服务拆分和业务中台建设,随着云计算和开源环 ...
- 使用 .NET 实现 Ajax 长连接
作者:http://www.cnblogs.com/cathsfz/ Ajax的长连接,或者有些人所说的Comet,就是指以XMLHttpRequest的方式连接服务器,连接后服务器并非即时写入相应并 ...
- 朴素、Select、Poll和Epoll网络编程模型实现和分析——Poll、Epoll模型处理长连接性能比较
在<朴素.Select.Poll和Epoll网络编程模型实现和分析--模型比较>一文中,我们分析了各种模型在处理短连接时的能力.本文我们将讨论处理长连接时各个模型的性能.(转载请指明出于b ...
- 长连接及在Node中的应用——HTTP/1.1 keep-alive
HTTP请求都要经过TCP三次握手建立连接,四次分手断开连,如果每个HTTP请求都要建立TCP连接的话是极其费时的,因此HTTP/1.1中浏览器默认开启了Connection: keep-alive. ...
- python使用socket实现协议TCP长连接框架
点击上方↑↑↑蓝字[协议分析与还原]关注我们 " 使用python实现协议中常见的TCP长连接框架." 分析多了协议就会发现,很多的应用,特别是游戏类和IM类应用,它们的协议会使用 ...
- 通da信TCP长连接数据算法分析
点击上方↑↑↑蓝字[协议分析与还原]关注我们 " 分析通da信TCP长连接内部分数据的算法." 作为一款老牌的炒股软件,通da信里面的数据是相当的丰富,免费的也很丰富,准确性也很好 ...
- 跨进程通信,到底用长连接还是短连接
一个完整的软件系统大多数情况下是由多个进程共同协作进行的,哪怕它们在同一台服务器上.所以,进程之间如何进行高效的通信至关重要. 单个应用程序+单个数据库这套基础开发套餐我相信每个人都经历过,甚至在初期 ...
- JAVA实现长连接(含心跳检测)Demo
实现原理: 长连接的维持,是要客户端程序,定时向服务端程序,发送一个维持连接包的. 如果,长时间未发送维持连接包,服务端程序将断开连接. 客户端: Client通过持有So ...
- 知乎千万级高性能长连接网关是如何搭建的
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 来源:https://www.xttblog.com/?p=487 ...
- TCP长连接与短链接
1. TCP连接 当网络通信时采用TCP协议时,在真正的读写操作之前,server与client之间必须建立一个连接,当读写操作完成后,双方不再需要这个连接时它们可以释放这个连接,连接的建立是需要三次 ...
最新文章
- 找论文太难?试试这款「文本生成」论文搜索工具丨开源
- 后台开发人员面试内容——操作系统(一)
- (字节/华为/美团)前端面经记录冷冷清清的金三银四
- java套接字客户端_使用Java从客户端套接字读取数据(Read data from a client socket in Java)...
- 矩池云安装gdal五种解决方案
- 31. Magento图片大小调整的相关代码
- 路由器连接、静态路由配置实例
- 手机号码检测开通微信
- 2022 携程提前批大数据一二(oc) 面经
- 用SAS如何读取数据
- 微信之父:张小龙并不孤独
- python做估值模型_通证估值模型-费雪模型与净现值模型详解
- 计算机在语文教学中,计算机技术在语文教学中的运用
- 安装ubuntu20.4桌面系统
- java中GUI中显示当前时间_javaGUI界面实现动态时间显示——Swing中的计时器Timer
- 想从事人工智能方面,需要自学什么?
- 形象理解二维傅里叶变换
- 报错: java.lang.IllegalArgumentException: mapper [categoryName] of different type, current_type [text]
- 苹果最新发布iOS 5 全部机型都有 下载吧
- leetcode 322. Coin Change-硬币交换|动态规划
热门文章
- HTML+CSS 制作下拉菜单
- Android11.0 SystemUI 修改下拉菜单快捷键的图标
- 新 IT 框架概述和双态 IT
- 【原创】基于FPGA的SDRAM控制器设计—自动刷新设计
- pudn下载地址的规律
- snort 错误 (CentOS 8)
- 2020年中国天线行业发展现状及细分市场结构分析[图]
- 在安装软件CAJViewer时出现,“错误1327。无效驱动器:F:
- Java并发机制的底层实现原理(Java并发编程的艺术整理)
- C语言实验源程序保存,c语言实验1程序开发环境.doc