Nginx WebSocket代理 #
一、WebSocket概述 #
1.1 什么是WebSocket #
WebSocket是一种在单个TCP连接上进行全双工通信的协议。与HTTP不同,WebSocket允许服务器主动向客户端推送数据。
1.2 WebSocket特点 #
- 全双工通信
- 低延迟
- 连接保持
- 二进制数据支持
- 跨域支持
1.3 WebSocket握手 #
WebSocket连接通过HTTP Upgrade请求建立:
text
GET /ws HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
服务器响应:
text
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
二、基本WebSocket代理 #
2.1 最简配置 #
nginx
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name ws.example.com;
location /ws {
proxy_pass http://backend:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
2.2 完整配置 #
nginx
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name ws.example.com;
location /ws {
proxy_pass http://backend:8080;
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 86400s;
proxy_send_timeout 86400s;
proxy_buffering off;
}
}
三、配置参数详解 #
3.1 Upgrade头处理 #
nginx
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
这个map指令根据客户端的Upgrade头设置Connection头:
- 如果有Upgrade头,设置Connection为upgrade
- 如果没有Upgrade头,设置Connection为close
3.2 超时配置 #
nginx
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
proxy_connect_timeout 60s;
| 参数 | 说明 | 默认值 |
|---|---|---|
| proxy_read_timeout | 读取后端响应超时 | 60s |
| proxy_send_timeout | 发送请求超时 | 60s |
| proxy_connect_timeout | 连接后端超时 | 60s |
WebSocket需要长连接,建议设置较长的超时时间。
3.3 缓冲配置 #
nginx
proxy_buffering off;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
WebSocket是实时通信,建议关闭缓冲。
3.4 HTTP版本 #
nginx
proxy_http_version 1.1;
WebSocket需要HTTP/1.1支持。
四、Socket.IO代理 #
4.1 基本配置 #
nginx
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name socket.example.com;
location /socket.io/ {
proxy_pass http://backend:3000;
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_read_timeout 86400s;
proxy_buffering off;
}
}
4.2 多实例配置 #
nginx
upstream socketio_servers {
ip_hash;
server backend1:3000;
server backend2:3000;
server backend3:3000;
}
server {
listen 80;
server_name socket.example.com;
location /socket.io/ {
proxy_pass http://socketio_servers;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_read_timeout 86400s;
}
}
4.3 Sticky Sessions #
nginx
upstream socketio_servers {
ip_hash;
server backend1:3000;
server backend2:3000;
}
sticky cookie srv_id expires=1h domain=.example.com path=/;
五、负载均衡 #
5.1 基本负载均衡 #
nginx
upstream ws_backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
server {
location /ws {
proxy_pass http://ws_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
5.2 会话保持 #
WebSocket需要会话保持,使用ip_hash:
nginx
upstream ws_backend {
ip_hash;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
或使用一致性哈希:
nginx
upstream ws_backend {
hash $remote_addr consistent;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
5.3 健康检查 #
nginx
upstream ws_backend {
zone ws_backend 64k;
server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
}
六、SSL/WSS配置 #
6.1 HTTPS + WSS #
nginx
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name ws.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name ws.example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
location /ws {
proxy_pass http://backend:8080;
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 86400s;
}
}
6.2 后端SSL连接 #
nginx
location /ws {
proxy_pass https://backend:8443;
proxy_ssl_verify off;
proxy_ssl_server_name on;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
七、不同框架配置 #
7.1 Node.js WebSocket #
nginx
location /ws {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 86400s;
}
7.2 Spring WebSocket #
nginx
location /ws {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_read_timeout 86400s;
}
7.3 Django Channels #
nginx
location /ws/ {
proxy_pass http://localhost:8001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_read_timeout 86400s;
}
7.4 Go WebSocket #
nginx
location /ws {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_read_timeout 86400s;
}
八、连接限制 #
8.1 连接数限制 #
nginx
limit_conn_zone $binary_remote_addr zone=ws_conn:10m;
server {
location /ws {
limit_conn ws_conn 10;
proxy_pass http://backend:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
8.2 请求频率限制 #
nginx
limit_req_zone $binary_remote_addr zone=ws_req:10m rate=10r/s;
server {
location /ws {
limit_req zone=ws_req burst=20;
proxy_pass http://backend:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
九、监控与调试 #
9.1 连接状态监控 #
nginx
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
9.2 日志配置 #
nginx
log_format ws '$remote_addr - [$time_local] "$request" '
'$status $body_bytes_sent '
'upstream=$upstream_addr '
'upgrade=$http_upgrade';
location /ws {
access_log /var/log/nginx/ws.access.log ws;
proxy_pass http://backend:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
9.3 调试技巧 #
nginx
error_log /var/log/nginx/error.log debug;
十、常见问题 #
10.1 连接断开 #
原因: 超时时间过短
解决:
nginx
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
10.2 403 Forbidden #
原因: Upgrade头未正确传递
解决:
nginx
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
10.3 跨域问题 #
解决:
nginx
location /ws {
proxy_pass http://backend:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type, Authorization";
if ($request_method = OPTIONS) {
return 204;
}
}
10.4 连接数过多 #
解决:
nginx
worker_processes auto;
worker_connections 65535;
worker_rlimit_nofile 65535;
十一、完整配置示例 #
nginx
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream ws_backend {
ip_hash;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
keepalive 32;
}
limit_conn_zone $binary_remote_addr zone=ws_conn:10m;
server {
listen 80;
server_name ws.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name ws.example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
location /ws {
limit_conn ws_conn 10;
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 86400s;
proxy_send_timeout 86400s;
proxy_connect_timeout 60s;
proxy_buffering off;
}
location /socket.io/ {
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_read_timeout 86400s;
proxy_buffering off;
}
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}
十二、总结 #
本章我们学习了:
- WebSocket原理:全双工通信和握手过程
- 基本配置:Upgrade头处理和超时设置
- Socket.IO代理:多实例和会话保持
- 负载均衡:ip_hash和一致性哈希
- SSL/WSS配置:HTTPS和WSS
- 不同框架:Node.js、Spring、Django、Go
- 连接限制:连接数和请求频率限制
- 监控调试:状态监控和日志配置
掌握WebSocket代理后,让我们进入下一章,学习限流限速!
最后更新:2026-03-27