答案:HTTP持久连接与版本演进
问题: 飞翔公司官网首页需要加载index.html、main.css、app.js、banner.jpg、logo.png共5个资源。在HTTP/1.1(无流水线)和HTTP/2环境下,分别需要几次TCP握手?为什么?
答案:
HTTP/1.1(无流水线)环境:1次TCP握手
航仔(后端工程师)向翼王(技术总监)解释道:HTTP/1.1默认启用了持久连接(Persistent Connection),也就是Connection: keep-alive。这意味着客户端和服务器建立一次TCP连接后,可以在这个连接上串行发送多个HTTP请求,而不需要为每个资源都重新进行TCP三次握手。
具体流程如下:
客户端 服务器
| -------- TCP三次握手 ----------> |
| -------- GET /index.html -----> |
| <------- 200 OK + HTML -------- |
| -------- GET /main.css -------> |
| <------- 200 OK + CSS --------- |
| -------- GET /app.js -----------> |
| <------- 200 OK + JS ---------- |
| -------- GET /banner.jpg ------> |
| <------- 200 OK + JPG --------- |
| -------- GET /logo.png --------> |
| <------- 200 OK + PNG --------- |
| -------- 连接保持或关闭 --------> |
虽然只需要1次TCP握手,但由于HTTP/1.1无流水线模式下请求是串行的,必须等前一个请求的响应返回后才能发下一个请求,所以5个资源会依次加载,存在**队头阻塞(Head-of-Line Blocking)**问题。
HTTP/2环境:1次TCP握手
凌叔(架构师)补充道:HTTP/2同样只需要1次TCP握手,但它在这个单一TCP连接上实现了多路复用(Multiplexing)。5个资源可以在同一个连接上并行传输,通过Stream ID区分不同的请求和响应。
客户端 服务器
| -------- TCP三次握手 ----------> |
| - Stream 1: GET /index.html --> |
| - Stream 3: GET /main.css ----> |
| - Stream 5: GET /app.js ------> |
| - Stream 7: GET /banner.jpg --> |
| - Stream 9: GET /logo.png -----> |
| <--- 响应交错返回(二进制帧)---- |
关键对比
| 特性 | HTTP/1.1(无流水线) | HTTP/2 |
|---|---|---|
| TCP握手次数 | 1次 | 1次 |
| 连接数 | 1个(串行) | 1个(多路复用) |
| 并发方式 | 串行,队头阻塞 | 并行,无队头阻塞 |
| 加载效率 | 低 | 高 |
总结: 两种协议都只需要1次TCP握手,但HTTP/2的多路复用让飞翔官网首页的加载速度大幅提升,用户体验更好。风速(性能测试工程师)实测发现,HTTP/2下首页加载时间比HTTP/1.1串行模式减少了约60%。