API 网关专栏 · 第 27

API 网关如何支持 WebSocket:架构、实现与最佳实践

2025年04月23日
API 网关如何支持 WebSocket:架构、实现与最佳实践

简介

WebSocket 是一种能够通过单一 TCP 连接在客户端和服务器之间实现全双工、持久通信的协议。与无状态且单向的 HTTP 不同,WebSocket 提供了低延迟的实时交互——这使其成为聊天应用、实时信息流、协同编辑和物联网 (IoT) 场景的理想选择。

在现代架构中,API 网关通常作为所有客户端流量的入口。通过 API 网关支持 WebSocket 流量需要特殊的处理机制,因为它偏离了 HTTP 的请求-响应模型。在本文中,我们将探讨 API 网关如何支持 WebSocket 连接、相关的架构考量以及实现的最佳实践。

什么是 WebSocket,它有何不同?

WebSocket 与 HTTP 对比

特性HTTPWebSocket
连接短暂的,每次请求独立持久的,全双工
协议请求-响应模型双向消息传递
开销较高(每个请求都带有请求头)低(仅需一次握手)
适用场景REST API、静态内容实时应用、数据流

WebSocket 握手

WebSocket 连接始于一个 HTTP Upgrade(升级)请求:

1GET /chat HTTP/1.1
2Host: server.example.com
3Upgrade: websocket
4Connection: Upgrade
5Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
6Sec-WebSocket-Version: 13

如果服务器支持 WebSocket,它会返回:

1HTTP/1.1 101 Switching Protocols
2Upgrade: websocket
3Connection: Upgrade
4Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

在此次握手完成后,连接即被升级,客户端和服务器都可以独立地发送消息了。

通过 API 网关路由 WebSocket 的挑战

  • 连接持久性:WebSocket 连接可能持续数小时。网关必须高效地管理这些长连接。
  • 负载均衡:与无状态的 HTTP 请求不同,WebSocket 会话必须保持粘性或一致的转发规则。
  • 协议升级支持:网关必须理解并支持 HTTP 的 Upgrade(升级)机制。
  • 监控与日志记录:实时流量比离散的 HTTP 请求更难进行审查和分析。
  • 安全性与限流:需要在不中断实时数据流的情况下执行安全策略。

架构:通过 API 网关的 WebSocket

🔁 流程图:API 网关中的 WebSocket 生命周期

1sequenceDiagram
2  participant Client
3  participant Gateway
4  participant Backend
5  Client->>Gateway: HTTP 升级请求
6  Gateway->>Backend: 代理升级请求
7  Backend-->>Gateway: 101 切换协议
8  Gateway-->>Client: 101 切换协议
9  Note over Client,Backend: WebSocket 隧道建立完成
10  Client-->>Backend: WebSocket 数据帧 (消息)
11  Backend-->>Client: WebSocket 数据帧 (回复)

网关职责

  • 接收并验证 Upgrade 请求
  • 维护 TCP 连接状态
  • 在客户端和后端之间转发数据帧
  • 应用可观测性和安全策略

不同 API 网关如何支持 WebSocket

Apache APISIX

  • 通过 websocket 路由选项提供原生的 WebSocket 代理功能
  • 支持基于 URI、请求头和查询参数进行路由
  • 提供支持速率限制和身份认证的插件

配置示例:

1{
2  "uri": "/ws",
3  "upstream": {
4    "type": "roundrobin",
5    "nodes": {
6      "192.168.1.10:8080": 1
7    }
8  },
9  "websocket": true
10}

Kong

  • 默认开启 WebSocket 支持
  • 可结合 TCP stream 插件进行 L4(四层)代理

Envoy

  • 在 HTTP 连接管理器中通过 use_websocket: true 支持 WebSocket
  • 全面支持基于请求头的路由

NGINX

  • 需要为 Upgrade 请求头进行专门配置
  • 没有原生的 WebSocket 感知能力——仅作为 TCP 隧道运行

配置示例:

1location /ws/ {
2  proxy_pass http://backend;
3  proxy_http_version 1.1;
4  proxy_set_header Upgrade $http_upgrade;
5  proxy_set_header Connection "Upgrade";
6}

API 网关中的 WebSocket 最佳实践

1. 开启连接的 Keep-Alive 和超时设置

  • 确保空闲连接在可配置的时间后被断开。
  • 监控并清理僵尸连接。

2. 必要时使用粘性会话 (Sticky Sessions)

  • 如果后端是有状态的,请配置会话粘性。
  • 使用请求头或 Cookie 来强制执行亲和性路由 (routing affinity)。

3. 实现每连接维度的速率限制

  • 通过统计每个客户端的消息数量或带宽来防止滥用。

4. 在初始的 HTTP 升级阶段进行身份认证

  • JWT 或 API 密钥验证应在握手完成前进行。

5. 监控连接与指标

  • 统计活跃的 WebSocket 会话数
  • 记录握手失败和异常终止的情况

📊 监控流程

1sequenceDiagram
2  participant Client
3  participant Gateway
4  participant Metrics
5  Client->>Gateway: WebSocket 请求
6  Gateway-->>Metrics: 记录升级尝试
7  Gateway-->>Client: 101 切换协议
8  Client-->>Gateway: WebSocket 数据帧
9  Gateway-->>Metrics: 记录消息计数/错误

总结

WebSocket 开启了实时应用的新篇章。API 网关可以支持 WebSocket 流量,但需要谨慎配置,以处理长连接、保持高性能并确保安全性。

选择一个从一开始就支持原生 WebSocket 路由,并且集成了指标监控和访问策略的 API 网关是明智之举。

常见问题 (FAQ)

1. WebSocket 可以通过网关用 TLS 加密吗?

答:可以。在客户端使用 wss://,并在网关或专用的 TLS 代理处终止 TLS。

2. WebSocket 能在像 Istio 这样的服务网格 (Service Mesh) 中使用吗?

答:可以,但请确保网格代理(如 Envoy)支持连接升级和 TCP 隧道。

3. 我该如何测试 WebSocket 端点?

答:可以使用如 wscat、浏览器开发者工具或支持 WebSocket 的 Postman 等工具。

4. WebSocket 可以实现负载均衡吗?

答:可以,但对于有状态的后端,请使用粘性会话或一致性哈希。

5. 我可以审查或拦截特定的 WebSocket 消息吗?

答:大多数网关会盲目地(不加区分地)代理消息。深度的数据包审查需要额外的中间件或支持 L7(七层)协议分析的代理。

微信咨询

获取方案