深入解析HTTP长连接原理

讲解长连接前,需要先了解短链接的原理,以及存在的问题

HTTP/1.0短链接
HTTP/1.0短链接机制

HTTP/1.0默认采用短链接,工作流程如下:

  1. **客户端发起连接请求:**客户端与服务端建立TCP连接(三次握手)

  2. **发起HTTP请求:**哭护短通过已建立的TCP连接发送HTTP请求报文

  3. **服务器处理请求:**服务器接收到请求,处理并生成HTTP响应报文

  4. **发起HTTP响应:**服务器通过同一个TCP连接发送响应报文给客户端

  5. 关闭TCP连接: 服务器或客户端在发送完响应或接受完响应后,立即关闭TCP连接(四次挥手)

  6. **重复上述步骤:**如果客户端需要获取更多资源,它必须重复上述所有步骤,重新建立TCP连接

短链接性能瓶颈
  1. TCP连接建立和关闭的开销

    • **三次握手:**每次建立TCP连接都需要客户端和服务端之间进行三次报文交互,一定程度上会带来网络消耗,同时连接的建立也需要消耗时间

    • **四次挥手:**同样,关闭TCP连接也需要多次报文交互,消耗时间

    • **慢启动:**TCP协议为避免网络阻塞,在建立连接初期会限制发送速率,导致一开始网络传输速率较慢,无法充分利用带宽

      慢启动原理详见另一篇博客:TCP如何实现流量控制-CSDN博客

  2. 服务器资源消耗

    • 每次建立和关闭连接,服务器都需要频繁进行套接字(socket)的创建和销毁,这会消耗大量CPU和内存资源
  3. 带宽利用率低下

    • 受连接频繁建立和关闭,以及慢启动的影响,TCP连接很难达到最大吞吐量,导致带宽利用率不高

这些问题最终会导致网页加载缓慢,用户体验差

HTTP/1.1长连接

长连接指在客户端和服务端建立一个TCP连接后,连接在完成一次请求后并不会立即关闭,而是保证开放状态,等待后续的HTTP请求。

长连接原理
  1. **客户端发起请求:**客户端与服务器建立TCP连接(三次握手)

  2. **发送HTTP请求:**客户端发送HTTP请求报文

  3. 服务器处理与响应: 服务器处理请求,发送HTTP响应报文

  4. **TCP连接保持开放:**服务器在发送完响应之后,不会立即关闭TCP连接,而是通过协商好的超时时间和最大请求数,保持连接开放

  5. **后续请求和复用连接:**客户端在需要获取其他资源时,可以通过这个已经建立的TCP连接发送新的HTTP请求,无需再进行TCP三次握手

  6. **连接关闭:**当客户端或服务端不再需要此链接(达到超时时间、客户端所有资源已获取,服务器资源限制等),会发起关闭TCP连接请求(四次挥手)

如何启用长连接

Connection:keep-alive

在HTTP/1.1中,长连接是默认的,客户端和服务器之间通过HTTP请求头 中包含的Connection:keep-alive来显式地协商是否保持连接,虽然HTTP/1.1规范中规定长连接是默认开启的,但为了兼容老旧客户端或代理,或者在某些特殊场景下,仍然会看到这个头部。

  • 客户端请求头

    复制代码
    GET /index.html HTTP/1.1
    Host: www.example.com
    Connection: keep-alive
  • 服务器响应头

    复制代码
    HTTP/1.1 200 OK
    Content-Type: text/html
    Content-Length: 1234
    Connection: keep-alive
    Keep-Alive: timeout=5, max=100

    服务器响应头中的Keep-Alive字段提供了详细的连接管理信息:

    • timeout:指定服务器保持连接的秒数,如果在指定时间内没有接收到新的请求,服务器将关闭连接

    • max:指定此次连接上允许发送的最大请求数量,到达此数量后,服务器关闭连接

如何关闭长连接
  1. 显式关闭

    • 客户端或服务器发送 Connection: close 头部

    • 任何一方都可以主动决定关闭连接

  2. 超时关闭

    服务器可以通过 Keep-Alive 头部设置超时时间和最大请求数,比如 `Keep-Alive: timeout=5, max=1000` 这表示连接在空闲5秒后会被关闭,或者最多处理1000个请求后关闭

  3. 错误或意外关闭

    • TCP连接本身出现错误、超时或中断

    • 一方意外崩溃

长连接优势
  1. 减少延迟:

    • 避免频繁三次握手和四次挥手:对于后续请求,不需要重新建立连接

    • **减少TCP慢启动影响:**TCP连接刚建立时,会有一个慢启动过程,限制发送速率,之后再慢慢提高发送速率,复用连接可以避免多次慢启动,保持较大的传输速率

  2. 降低服务器资源消耗:

    • 减少服务器频繁创建和销毁套接字的开销,降低服务器CPU和内存压力

    • TCP连接复用意味着服务器不需要进行频繁的状态切换,有助于服务器处理更多并发连接

  3. 提高带宽利用率:

    • 连接在较长时间内允许数据传输,能更好利用可用网络带宽
长连接局限性
  • 请求的队头阻塞: 在HTTP/1.1中,即使使用了长连接,客户端也必须严格按照请求的顺序发送。也就是说,在一个TCP连接上,客户端发送完第一个请求后,必须等待服务器的响应,才能发送第二个请求。如果第一个请求的处理时间较长,或者传输过程中某个响应丢失,那么后续的所有请求都将被阻塞

  • 管道化尝试与失败: HTTP/1.1引入了管道化机制,试图缓解队头阻塞。它允许客户端在收到前一个响应之前,就发送多个请求。服务器也会按顺序处理这些请求并发送响应。然而,管道化在实际应用中遇到了很多问题:

    • 服务器响应顺序必须与请求顺序一致: 如果服务器处理第一个请求耗时很长,即使它已经处理完了后续的请求,也必须等待第一个请求的响应发送完成后才能发送。这实际上是将队头阻塞从客户端请求端转移到了服务器响应端。

    • 代理和中间件的兼容性问题: 很多老的代理服务器和中间件不支持HTTP管道化,或者实现不完善,导致其普及度非常低。

    • 连接断开后的重试复杂性: 如果管道化发送了多个请求,但连接在某个响应返回前断开,客户端很难判断哪些请求已经成功,哪些需要重试,增加了实现的复杂性。

    • 由于这些限制,HTTP/1.1最终没有被广泛应用,对头阻塞问题,成为推动HTTP协议进一步演进的重要动力

相关推荐
q***64972 小时前
头歌答案--爬虫实战
java·前端·爬虫
凌波粒2 小时前
SpringMVC基础教程(4)--Ajax/拦截器/文件上传和下载
java·前端·spring·ajax
q***55582 小时前
SpringBoot项目中替换指定版本的tomcat
spring boot·后端·tomcat
汤姆yu2 小时前
基于springboot的电脑商城系统
java·spring boot·后端
未若君雅裁2 小时前
LeetCode 51 - N皇后问题 详解笔记
java·数据结构·笔记·算法·leetcode·剪枝
码事漫谈2 小时前
Visual Studio 2026真的值得升级吗中国开发者实测报告
后端
kkce2 小时前
快快科技 MTR 路由检测全面支持 IPv6,多节点覆盖赋能全协议网络诊断
服务器·网络·科技
失散132 小时前
架构师级别的电商项目——2 电商项目核心需求分析
java·分布式·微服务·架构·需求分析
acrel158215962213 小时前
新品!分布式新能源群调群控装置!ANet-4E16S-AGVC 装置让分布式发电更智能、更高效
网络·安科瑞电气·分布式新能源群调群控装置·微电网能源管理