Nginx 报错 unknown connection_upgrade variable 完整解决方案
问题描述
在使用 Nginx 配置 WebSocket 或反向代理时,可能会遇到以下错误:
nginx: [emerg] unknown "connection_upgrade" variable
nginx: configuration file /etc/nginx/nginx.conf test failed
这个错误表明 Nginx 配置文件中使用了 $connection_upgrade 变量,但该变量未定义。
错误原因
$connection_upgrade 变量通常用于 WebSocket 配置,支持 Upgrade 头部的处理。但 Nginx 默认不识别这个变量,需要通过 map 指令手动定义。
常见触发场景
| 场景 | 是否需要 WebSocket | 常见配置 |
|---|---|---|
| 普通 Web 应用 | ❌ 不需要 | HTTP/HTTPS |
| 实时聊天应用 | ✅ 需要 | WebSocket |
| API 网关 | ❌ 不需要 | REST API |
| 在线协作工具 | ✅ 需要 | WebSocket |
| 直播/流媒体 | ✅ 需要 | WebSocket/RTMP |
解决方案
方案一:添加 map 配置(推荐 - 需要 WebSocket)
如果你需要 WebSocket 支持,在 /etc/nginx/nginx.conf 的 http 块中添加以下配置:
http {
# ... 其他配置 ...
# 添加 WebSocket 支持的 map 配置
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# ... 其他配置 ...
}
配置说明
- map 指令:根据
$http_upgrade的值设置$connection_upgrade - default upgrade:默认情况下允许 Upgrade
- '' close:如果 Upgrade 头为空,则关闭连接
完整配置示例
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# WebSocket 支持配置
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# 基础配置
sendfile on;
keepalive_timeout 65;
# 上游服务器
upstream backend {
server 127.0.0.1:8080;
}
# 服务器配置
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
# WebSocket 支持
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;
}
}
}
方案二:移除 WebSocket 配置(不需要 WebSocket)
如果你不需要 WebSocket 支持,可以直接移除相关配置:
location / {
proxy_pass http://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_set_header Upgrade $http_upgrade;
# proxy_set_header Connection $connection_upgrade;
}
方案三:使用独立的 WebSocket 配置文件
将 WebSocket 配置提取到独立文件,便于管理:
# 创建 WebSocket 配置文件
sudo tee /etc/nginx/conf.d/websocket.conf << 'EOF'
# WebSocket 支持配置
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
EOF
# 在 nginx.conf 中引用
# http 块中添加:
include /etc/nginx/conf.d/*.conf;
验证和测试
1. 测试配置文件
# 测试 Nginx 配置
sudo nginx -t
# 成功输出示例:
# nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
# nginx: configuration file /etc/nginx/nginx.conf test is successful
2. 重载 Nginx
# 重载配置(推荐)
sudo nginx -s reload
# 或者重启服务
sudo systemctl restart nginx
# 检查状态
sudo systemctl status nginx
3. 验证 WebSocket 连接
# 使用 curl 测试 Upgrade 头
curl -i -H "Upgrade: websocket" -H "Connection: Upgrade" http://example.com
# 使用 wscat 测试 WebSocket(需要安装)
npm install -g wscat
wscat -c ws://example.com/websocket
4. 查看 Nginx 日志
# 查看错误日志
sudo tail -f /var/log/nginx/error.log
# 查看访问日志
sudo tail -f /var/log/nginx/access.log
# 实时查看连接状态
sudo nginx -T | grep -A 10 "location"
常见问题排查
问题 1:配置后仍然报错
# 检查 map 配置位置(必须在 http 块内)
sudo nginx -T | grep -A 5 "map"
# 检查配置文件语法
sudo nginx -t
# 检查文件权限
ls -la /etc/nginx/nginx.conf
问题 2:WebSocket 连接失败
# 检查后端服务是否运行
netstat -tlnp | grep 8080
# 检查防火墙规则
sudo ufw status
sudo firewall-cmd --list-ports
# 测试后端直连
curl http://127.0.0.1:8080
问题 3:配置不生效
# 强制重载 Nginx
sudo systemctl stop nginx
sudo systemctl start nginx
# 检查是否有多个 nginx.conf
find /etc -name "nginx.conf"
# 查看实际加载的配置
sudo nginx -T
性能优化建议
WebSocket 连接优化
http {
# ... 其他配置 ...
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# WebSocket 超时配置
map $http_upgrade $timeout_upgrade {
default 3600s;
'' 75s;
}
server {
location /websocket {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# 优化配置
proxy_buffering off;
proxy_cache off;
proxy_read_timeout $timeout_upgrade;
proxy_send_timeout $timeout_upgrade;
}
}
}
连接池配置
upstream backend {
server 127.0.0.1:8080;
# 连接池配置
keepalive 32;
keepalive_requests 100;
keepalive_timeout 60s;
}
安全加固建议
1. 限制 WebSocket 路径
# 只允许特定路径使用 WebSocket
location /api/ws {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
# 其他路径禁止 WebSocket
location / {
proxy_pass http://backend;
# 检查是否尝试 Upgrade
if ($http_upgrade) {
return 400;
}
}
2. 添加认证
location /websocket {
# JWT 认证
auth_request /auth;
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
location = /auth {
internal;
proxy_pass http://auth-service/validate;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
}
3. 限流配置
http {
# 限制连接速率
limit_conn_zone $binary_remote_addr zone=websocket_limit:10m;
server {
location /websocket {
limit_conn websocket_limit 10; # 每个 IP 最多 10 个连接
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
}
总结
Nginx 报错 unknown "connection_upgrade" variable 的解决方案:
- 需要 WebSocket:在 http 块中添加 map 配置定义变量
- 不需要 WebSocket:移除 Upgrade 相关配置
- 验证配置:使用
nginx -t测试,nginx -s reload重载 - 性能优化:配置超时、连接池、缓冲
- 安全加固:路径限制、认证、限流
根据你的实际需求选择合适的方案,确保 Nginx 配置正确运行!🚀
相关文章:
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。




