服务器 > 网络 > websocket

Nginx反向代理WebSocket的配置详解与参数实战指南

64人参与 • 2026-09-23 • websocket

在生产环境中部署实时通信服务时,nginx 作为反向代理是不可或缺的基础设施。然而,websocket 协议与传统的 http 请求在底层机制上存在本质差异,直接套用常规的 nginx 代理配置必然导致连接失败或频繁断开。

一、 标准配置示例

以下是一套经过生产环境验证的 nginx websocket 代理最小完备配置。建议将 websocket 路由与常规 http api 路由隔离,分配独立的 location 块以便独立管理生命周期。

# 【全局配置】定义连接升级变量的映射关系(必须放在 http {} 块内)
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

# 【上游配置】定义后端 websocket 服务集群
upstream ws_backend {
    server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
    keepalive 64;
}

server {
    listen 443 ssl;
    server_name ws.example.com;

    # ssl 配置(生产环境强制使用 wss)
    ssl_certificate     /etc/nginx/ssl/ws.example.com.pem;
    ssl_certificate_key /etc/nginx/ssl/ws.example.com.key;

    location /ws/ {
        proxy_pass http://ws_backend;

        # ========== 核心三要素(缺一不可)==========
        proxy_http_version 1.1;
        proxy_set_header upgrade $http_upgrade;
        proxy_set_header connection $connection_upgrade;

        # ========== 元数据透传 ==========
        proxy_set_header host $host;
        proxy_set_header x-real-ip $remote_addr;
        proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
        proxy_set_header x-forwarded-proto $scheme;

        # ========== 超时与缓冲控制 ==========
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
        proxy_buffering off;
        proxy_request_buffering off;
    }
}

二、 核心参数逐项解析

理解上述配置中的每一个指令,是排查问题和深度调优的前提。下面按功能模块对关键参数进行结构化讲解。

1. 协议升级相关参数

这是 nginx 支持 websocket 的根基,缺少任何一项都会导致握手失败。

参数默认值作用说明为什么必须配置
proxy_http_version1.0指定 nginx 与上游服务器通信使用的 http 协议版本websocket 握手依赖 http/1.1 的 upgrade 机制,http/1.0 不支持该机制,上游收不到升级请求头会直接返回 400
proxy_set_header upgrade无将客户端请求中的 upgrade 头原样透传给上游nginx 默认不会转发 upgrade 和 connection 这两个逐跳头(hop-by-hop header),必须显式传递
proxy_set_header connection无根据客户端请求动态设置发往上游的 connection 头不能写死为 upgrade,否则普通 http 请求(如健康检查)也会被标记为升级请求,导致上游解析异常
map $http_upgrade ...无定义变量映射规则:有 upgrade 头时值为 upgrade,否则为 close配合上一条指令实现智能路由,让同一个 location 同时兼容 websocket 和普通 http 请求

重点提示:map 指令必须放置在 http {} 块的顶层,不能放在 server 或 location 内部,否则 nginx 启动时会报语法错误。

2. 超时控制参数

websocket 是持久长连接,默认的超时配置完全不适用,这是生产环境中连接“无故断开”的最常见原因。

参数默认值作用说明生产调优建议
proxy_read_timeout60s两次连续读取上游响应之间的最大空闲等待时间根据业务心跳间隔设置,通常为心跳周期的 2~3 倍。若链路中有 cdn/slb,必须大于中间件的空闲超时时间
proxy_send_timeout60s两次连续向上游发送请求之间的最大空闲等待时间与 proxy_read_timeout 保持一致,防止单向数据传输时另一端超时断连
proxy_connect_timeout60s与上游建立 tcp 连接的超时时间一般保持默认即可,若后端在高负载下握手慢可适当调大至 10~30s

避坑指南:proxy_read_timeout 不是“连接的总存活时间”,而是“两次数据帧之间的最大空闲间隔”。只要客户端或服务端在超时时间内发送了任意数据(包括 ping/pong 心跳帧),计时器就会重置。因此,应用层心跳是维持长连接的必要手段,仅靠调大超时值无法从根本上解决问题。

3. 缓冲与性能参数

websocket 要求低延迟的实时数据传输,默认的缓冲机制会严重破坏这一特性。

参数默认值作用说明为什么必须关闭
proxy_bufferingon控制是否缓存上游的响应体开启时 nginx 会将上游数据攒够一定量再发给客户端,导致消息延迟、乱序,违背实时通信的设计初衷
proxy_request_bufferingon控制是否缓存客户端的请求体websocket 双向通信,客户端发送的数据同样需要实时透传,不能缓冲
keepalive (upstream)无维持 nginx 到上游的空闲 tcp 连接池大小减少握手阶段的 tcp 三次握手和 tls 握手开销,提升连接建立速度。注意:ws 连接建立后会被独占,此连接池主要服务于握手和健康检查

4. 元数据透传参数

这些参数确保后端服务能够获取真实的客户端信息,是安全审计和业务逻辑的基础。

参数作用说明注意事项
host $host透传原始域名后端框架通常依赖 host 头进行路由匹配和跨域校验,不透传会导致 404 或 403
x-real-ip $remote_addr传递客户端真实 ip仅传递直连 nginx 的 ip,若 nginx 前还有 lb,需改用 x-forwarded-for
x-forwarded-for $proxy_add_x_forwarded_for追加客户端 ip 到已有链路链多级代理时必须使用,保留完整的访问链路溯源信息
x-forwarded-proto $scheme传递原始协议(http/https)后端判断是否启用 wss、生成回调 url 时依赖此头

三、 生产环境必做的三项加固

掌握了基础参数后,还需要针对生产环境的特殊性进行加固,避免上线后出现安全事故或性能瓶颈。

1. 并发连接数限制(防资源耗尽攻击)

恶意用户可以轻易建立大量 websocket 连接耗尽服务器文件描述符。必须在 nginx 层设置单 ip 并发上限:

# http 块中定义共享内存区域
limit_conn_zone $binary_remote_addr zone=ws_conn_limit:10m;

# location 块中应用限制
limit_conn ws_conn_limit 20;      # 单 ip 最多 20 个并发 ws 连接
limit_conn_status 503;            # 超限返回 503 service unavailable

2. 握手速率限制(防 cc 攻击)

高频的连接/断开操作比持久连接更消耗 cpu 资源,需限制握手请求频率:

# http 块中定义限速区域
limit_req_zone $binary_remote_addr zone=ws_req_limit:10m rate=10r/s;

# location 块中应用限速
limit_req zone=ws_req_limit burst=20 nodelay;

3. 系统内核参数调优

每个 websocket 连接占用一个文件描述符,万级并发下默认内核参数会成为瓶颈。需在 /etc/sysctl.conf 中调整:

# 提升系统级文件描述符上限
fs.file-max = 1048576
fs.nr_open = 1048576

# 扩大本地端口范围,防止 nginx 连接上游时端口耗尽
net.ipv4.ip_local_port_range = 1024 65535

# 优化 tcp keepalive 作为应用层心跳的兜底
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3

修改后执行 sysctl -p 生效,同时确保 nginx 配置中 worker_rlimit_nofile 的值大于等于 worker_connections × worker_processes。

四、 常见故障速查表

当 websocket 连接异常时,可根据以下对照表快速定位问题根因:

现象可能原因排查与解决方案
握手返回 400上游未收到 upgrade 头检查是否遗漏 proxy_http_version 1.1;抓包确认 nginx 发往后端的请求头
握手返回 502后端拒绝连接或握手完成前断开检查后端服务是否存活、端口是否正确;查看后端应用日志是否有鉴权/路径匹配失败
连接建立后固定时间断开中间件空闲超时确认链路中 cdn/slb/waf 的空闲超时时间,确保 proxy_read_timeout 大于该值,并实现应用层心跳
消息延迟或乱序代理缓冲未关闭检查 proxy_buffering off 和 proxy_request_buffering off 是否生效
高并发下新连接被拒绝文件描述符或端口耗尽检查 ulimit -n、worker_rlimit_nofile、ip_local_port_range 是否已调优
后端报 broken pipenginx 先于应用层断开连接确保 nginx 的 proxy_read_timeout 大于后端应用层设置的读超时时间

到此这篇关于nginx反向代理websocket的配置详解与参数实战指南的文章就介绍到这了,更多相关nginx反向代理websocket内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

赞 (0)

您想发表意见!!点此发布评论

推荐阅读

K8s部署tomcat的步骤和出现的一些问题

09-23

Nginx中反向代理WebSocket的常见问题与避坑指南

09-23

Nginx将WebSocket ws视频流转换为wss视频流的配置方案

09-20

在Ubuntu系统中修改DNS的多种操作方法

02-07

nginx配置长连接、短连接、WebSocket的实现步骤

02-07

深入理解NumPy 的 np.column_stack的实现

01-07

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论