HTTP Keep-Alive 机制

理解 HTTP 长连接的作用与工作原理

问题

Keep-Alive 的作用与原理是什么?

解答

什么是 Keep-Alive

Keep-Alive 是 HTTP 的持久连接机制,允许在单个 TCP 连接上发送多个 HTTP 请求/响应,避免每次请求都重新建立连接。

短连接 vs 长连接

短连接 (HTTP/1.0 默认):
请求1: TCP握手 → 请求 → 响应 → TCP挥手
请求2: TCP握手 → 请求 → 响应 → TCP挥手
请求3: TCP握手 → 请求 → 响应 → TCP挥手

长连接 (HTTP/1.1 默认):
TCP握手 → 请求1 → 响应1 → 请求2 → 响应2 → 请求3 → 响应3 → TCP挥手

HTTP 头部设置

# 请求头 - 开启长连接
Connection: keep-alive
Keep-Alive: timeout=5, max=100

# 请求头 - 关闭长连接
Connection: close

参数说明:

  • timeout=5:连接空闲 5 秒后关闭
  • max=100:该连接最多处理 100 个请求

Node.js 服务端配置

const http = require('http');

const server = http.createServer((req, res) => {
  res.writeHead(200, {
    'Content-Type': 'text/plain',
    // 设置长连接参数
    'Connection': 'keep-alive',
    'Keep-Alive': 'timeout=5, max=100'
  });
  res.end('Hello World');
});

// 设置服务器的 keep-alive 超时时间
server.keepAliveTimeout = 5000; // 5秒
server.headersTimeout = 6000;   // 略大于 keepAliveTimeout

server.listen(3000);

Nginx 配置示例

http {
    # 开启长连接
    keepalive_timeout 65;      # 连接超时时间
    keepalive_requests 100;    # 单连接最大请求数
    
    # 与上游服务器的长连接
    upstream backend {
        server 127.0.0.1:8080;
        keepalive 32;          # 连接池大小
    }
}

浏览器中查看连接复用

// 连续发送多个请求,观察 Network 面板的 Connection ID
async function testKeepAlive() {
  for (let i = 0; i < 5; i++) {
    await fetch('/api/data');
    console.log(`请求 ${i + 1} 完成`);
  }
}

// 在 Chrome DevTools Network 面板中
// 右键表头 → 勾选 "Connection ID"
// 相同 ID 表示复用了同一个 TCP 连接

HTTP 版本差异

版本默认行为说明
HTTP/1.0短连接需显式设置 Connection: keep-alive
HTTP/1.1长连接需显式设置 Connection: close 关闭
HTTP/2多路复用单连接并行多个请求,更高效

关键点

  • 减少开销:避免重复 TCP 三次握手和四次挥手
  • HTTP/1.1 默认开启:无需额外配置,除非显式关闭
  • 有超时限制:空闲连接会在 timeout 后关闭,防止资源浪费
  • 有请求上限:max 参数限制单连接的请求数量
  • HTTP/2 更优:多路复用解决了 Keep-Alive 的队头阻塞问题