使用长连接能够减少建立销毁连接的消耗,三次握手、四次挥手对性能影响是很大的。一般 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;

关于长连接,有两个参数需要注意:

  1. keepalive_timeout:连接不活跃多长时间后断开,如果服务端(nginx)设置的时间比客户端短的话,可能会导致客户端请求异常。前提是 HTTPClient 都 http.connection.stalecheck 参数置为 false,也就是不在请求前检查连接的有效性。
  2. 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 异常,需要对其进行特殊处理,进行适当的重试。

资料

  1. nginx 优化

关于 HTTP 长连接相关推荐

  1. php 长连接心跳_支持gRPC长链接,深度解读Nacos2.0架构设计及新模型

    作者 | 杨翊(席翁) Nacos PMC 来源|阿里巴巴云原生公众号 Nacos 简介 Nacos 在阿里巴巴起源于 2008 年五彩石项目,该项目完成了微服务拆分和业务中台建设,随着云计算和开源环 ...

  2. 使用 .NET 实现 Ajax 长连接

    作者:http://www.cnblogs.com/cathsfz/ Ajax的长连接,或者有些人所说的Comet,就是指以XMLHttpRequest的方式连接服务器,连接后服务器并非即时写入相应并 ...

  3. 朴素、Select、Poll和Epoll网络编程模型实现和分析——Poll、Epoll模型处理长连接性能比较

    在<朴素.Select.Poll和Epoll网络编程模型实现和分析--模型比较>一文中,我们分析了各种模型在处理短连接时的能力.本文我们将讨论处理长连接时各个模型的性能.(转载请指明出于b ...

  4. 长连接及在Node中的应用——HTTP/1.1 keep-alive

    HTTP请求都要经过TCP三次握手建立连接,四次分手断开连,如果每个HTTP请求都要建立TCP连接的话是极其费时的,因此HTTP/1.1中浏览器默认开启了Connection: keep-alive. ...

  5. python使用socket实现协议TCP长连接框架

    点击上方↑↑↑蓝字[协议分析与还原]关注我们 " 使用python实现协议中常见的TCP长连接框架." 分析多了协议就会发现,很多的应用,特别是游戏类和IM类应用,它们的协议会使用 ...

  6. 通da信TCP长连接数据算法分析

    点击上方↑↑↑蓝字[协议分析与还原]关注我们 " 分析通da信TCP长连接内部分数据的算法." 作为一款老牌的炒股软件,通da信里面的数据是相当的丰富,免费的也很丰富,准确性也很好 ...

  7. 跨进程通信,到底用长连接还是短连接

    一个完整的软件系统大多数情况下是由多个进程共同协作进行的,哪怕它们在同一台服务器上.所以,进程之间如何进行高效的通信至关重要. 单个应用程序+单个数据库这套基础开发套餐我相信每个人都经历过,甚至在初期 ...

  8. JAVA实现长连接(含心跳检测)Demo

    实现原理: 长连接的维持,是要客户端程序,定时向服务端程序,发送一个维持连接包的.        如果,长时间未发送维持连接包,服务端程序将断开连接. 客户端:        Client通过持有So ...

  9. 知乎千万级高性能长连接网关是如何搭建的

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 来源:https://www.xttblog.com/?p=487 ...

  10. TCP长连接与短链接

    1. TCP连接 当网络通信时采用TCP协议时,在真正的读写操作之前,server与client之间必须建立一个连接,当读写操作完成后,双方不再需要这个连接时它们可以释放这个连接,连接的建立是需要三次 ...

最新文章

  1. 找论文太难?试试这款「文本生成」论文搜索工具丨开源
  2. 后台开发人员面试内容——操作系统(一)
  3. (字节/华为/美团)前端面经记录冷冷清清的金三银四
  4. java套接字客户端_使用Java从客户端套接字读取数据(Read data from a client socket in Java)...
  5. 矩池云安装gdal五种解决方案
  6. 31. Magento图片大小调整的相关代码
  7. 路由器连接、静态路由配置实例
  8. 手机号码检测开通微信
  9. 2022 携程提前批大数据一二(oc) 面经
  10. 用SAS如何读取数据
  11. 微信之父:张小龙并不孤独
  12. python做估值模型_通证估值模型-费雪模型与净现值模型详解
  13. 计算机在语文教学中,计算机技术在语文教学中的运用
  14. 安装ubuntu20.4桌面系统
  15. java中GUI中显示当前时间_javaGUI界面实现动态时间显示——Swing中的计时器Timer
  16. 想从事人工智能方面,需要自学什么?
  17. 形象理解二维傅里叶变换
  18. 报错: java.lang.IllegalArgumentException: mapper [categoryName] of different type, current_type [text]
  19. 苹果最新发布iOS 5 全部机型都有 下载吧
  20. leetcode 322. Coin Change-硬币交换|动态规划

热门文章

  1. HTML+CSS 制作下拉菜单
  2. Android11.0 SystemUI 修改下拉菜单快捷键的图标
  3. 新 IT 框架概述和双态 IT
  4. 【原创】基于FPGA的SDRAM控制器设计—自动刷新设计
  5. pudn下载地址的规律
  6. snort 错误 (CentOS 8)
  7. 2020年中国天线行业发展现状及细分市场结构分析[图]
  8. 在安装软件CAJViewer时出现,“错误1327。无效驱动器:F:
  9. Java并发机制的底层实现原理(Java并发编程的艺术整理)
  10. C语言实验源程序保存,c语言实验1程序开发环境.doc