🔌 在现代Web应用中,WebSocket技术为实时通信提供了强大的支持。本文将详细介绍如何在Nginx中正确配置WebSocket反向代理,包括配置方法、常见问题解决以及获取真实IP的方法。
📋 配置前的准备工作 在开始配置WebSocket代理之前,需要确保你的环境具备以下条件:
Nginx已正确安装并运行
具有管理员权限或sudo访问权限
WebSocket后端服务已部署并正常运行
了解基本的Nginx配置语法
🔍 查找Nginx配置文件 首先,我们需要找到Nginx的配置文件位置:
1 2 3 4 5 6 7 8 find / -name nginx.conf 2>/dev/null locate nginx.conf ps aux | grep nginx
常见的Nginx配置文件位置 :
/etc/nginx/nginx.conf(系统包管理器安装)/usr/local/nginx/conf/nginx.conf(源码编译安装)/opt/nginx/conf/nginx.conf(自定义安装)
⚙️ WebSocket代理配置 基本配置结构 编辑Nginx配置文件:
1 2 vim /usr/local/nginx/conf/nginx.conf
在http块内添加以下完整的server配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 server { listen 80 ; server_name robotchat.lukeewin.top; location / { proxy_pass http://127.0.0.1:9090; 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 ; } location /onlineCount { proxy_redirect off ; proxy_pass http://127.0.0.1:9090; 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_http_version 1 .1 ; proxy_set_header Upgrade $http_upgrade ; proxy_set_header Connection "upgrade" ; proxy_read_timeout 36000s ; proxy_send_timeout 36000s ; proxy_connect_timeout 60s ; } }
关键配置解析 graph TD
A[客户端WebSocket请求] --> B[Nginx反向代理]
B --> C{检查请求头}
C -->|Upgrade: websocket| D[启用WebSocket代理]
C -->|普通HTTP| E[普通HTTP代理]
D --> F[设置Connection: upgrade]
D --> G[设置HTTP版本1.1]
D --> H[配置超时时间]
F --> I[转发到后端服务]
G --> I
H --> I
E --> I
I --> J[后端WebSocket服务]
配置参数详细说明
配置项
作用
必需性
proxy_http_version 1.1
启用HTTP/1.1协议
必需
proxy_set_header Upgrade $http_upgrade
转发协议升级头
必需
proxy_set_header Connection "upgrade"
设置连接升级
必需
proxy_read_timeout 36000s
读取超时时间
重要
proxy_send_timeout 36000s
发送超时时间
重要
proxy_connect_timeout 60s
连接超时时间
推荐
重要提醒 :如果不设置 proxy_read_timeout 和 proxy_send_timeout,WebSocket连接可能会因超时而报 EOFException 错误。
🌐 获取客户端真实IP 必要的代理头配置 为了在后端服务中获取客户端的真实IP地址,必须添加以下三个代理头:
1 2 3 proxy_set_header Host $host ;proxy_set_header X-Real-IP $remote_addr ;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for ;
Java后端获取真实IP的代码实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 public String getRealIp (HttpServletRequest request) { String ip = request.getHeader("X-Forwarded-For" ); if (StringUtils.isNotEmpty(ip) && !"unknown" .equalsIgnoreCase(ip)) { int index = ip.indexOf("," ); if (index != -1 ) { return ip.substring(0 , index).trim(); } else { return ip.trim(); } } ip = request.getHeader("X-Real-IP" ); if (StringUtils.isNotEmpty(ip) && !"unknown" .equalsIgnoreCase(ip)) { return ip.trim(); } ip = request.getHeader("X-Forwarded-For" ); if (StringUtils.isNotEmpty(ip) && !"unknown" .equalsIgnoreCase(ip)) { return ip.split("," )[0 ].trim(); } return request.getRemoteAddr(); }
IP获取优先级说明 graph TD
A[开始获取IP] --> B{检查X-Forwarded-For}
B -->|存在且有效| C[提取第一个IP]
B -->|不存在或无效| D{检查X-Real-IP}
C --> E[返回IP地址]
D -->|存在且有效| F[返回X-Real-IP]
D -->|不存在或无效| G[返回RemoteAddr]
F --> E
G --> E
🔧 高级配置选项 SSL/HTTPS配置 如果你的网站使用HTTPS,需要额外配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 server { listen 443 ssl http2; server_name your-domain.com; ssl_certificate /path/to/your/cert.pem; ssl_certificate_key /path/to/your/key.pem; location /ws { proxy_pass http://127.0.0.1:9090; 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_http_version 1 .1 ; proxy_set_header Upgrade $http_upgrade ; proxy_set_header Connection "upgrade" ; proxy_read_timeout 36000s ; proxy_send_timeout 36000s ; proxy_connect_timeout 60s ; } }
负载均衡配置 对于高可用场景,可以配置多个后端服务:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 upstream websocket_backend { ip_hash; server 127.0.0.1:9090 ; server 127.0.0.1:9091 ; server 127.0.0.1:9092 ; }server { listen 80 ; server_name your-domain.com; location /ws { proxy_pass http://websocket_backend; } }
📝 配置验证和重启 检查配置语法 1 2 3 4 5 6 7 8 nginx -t nginx -s reload systemctl restart nginx
测试WebSocket连接 可以使用以下方法测试WebSocket连接:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 const ws = new WebSocket ('ws://your-domain.com/onlineCount' ); ws.onopen = function (event ) { console .log ('WebSocket连接已建立' ); }; ws.onmessage = function (event ) { console .log ('收到消息:' , event.data ); }; ws.onerror = function (error ) { console .error ('WebSocket错误:' , error); }; ws.onclose = function (event ) { console .log ('WebSocket连接已关闭' ); };
🚨 常见问题及解决方案 1. EOFException错误 原因 :未设置适当的超时时间
解决方案 :
1 2 proxy_read_timeout 36000s ;proxy_send_timeout 36000s ;
2. 连接被意外关闭 原因 :缺少WebSocket升级头
解决方案 :
1 2 3 proxy_http_version 1 .1 ;proxy_set_header Upgrade $http_upgrade ;proxy_set_header Connection "upgrade" ;
3. 无法获取真实IP 原因 :缺少代理头配置
解决方案 :
1 2 3 proxy_set_header Host $host ;proxy_set_header X-Real-IP $remote_addr ;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for ;
4. 502 Bad Gateway 可能原因 :
检查方法 :
1 2 3 4 5 netstat -tlnp | grep 9090tail -f /var/log/nginx/error.log
📊 性能优化建议
合理设置超时时间 :根据业务需求调整超时参数
启用gzip压缩 :对于文本消息可以减少带宽使用
使用ip_hash :在负载均衡中保持会话粘性
监控连接数 :防止连接数过多导致服务器压力
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 upstream websocket_backend { ip_hash; server 127.0.0.1:9090 weight=1 max_fails=3 fail_timeout=30s ; server 127.0.0.1:9091 weight=1 max_fails=3 fail_timeout=30s ; }server { listen 80 ; server_name your-domain.com; return 301 https://$server_name $request_uri ; }server { listen 443 ssl http2; server_name your-domain.com; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; ssl_protocols TLSv1.2 TLSv1.3 ; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384; location / { proxy_pass http://websocket_backend; 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 ; } location /ws { proxy_pass http://websocket_backend; 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_http_version 1 .1 ; proxy_set_header Upgrade $http_upgrade ; proxy_set_header Connection "upgrade" ; proxy_connect_timeout 60s ; proxy_read_timeout 36000s ; proxy_send_timeout 36000s ; proxy_buffering off ; } access_log /var/log/nginx/websocket_access.log; error_log /var/log/nginx/websocket_error.log; }
📝 总结 通过本文的配置指南,你应该能够成功在Nginx中配置WebSocket反向代理。关键要点包括:
必需的WebSocket头 :Upgrade、Connection、HTTP版本1.1
合适的超时设置 :防止连接意外断开
真实IP获取 :正确配置代理头信息
错误排查 :了解常见问题及解决方法
正确的Nginx WebSocket配置不仅能确保实时通信的稳定性,还能为你的Web应用提供更好的用户体验。记住在生产环境中要进行充分的测试,并根据实际负载情况调整相关参数。