在使用 Nginx 做反向代理时,经常会遇到一些看似莫名其妙的问题,比如返回 502 错误、路径出错、真实 IP 丢失等等。本文总结了开发和部署中最常见的 Nginx 反向代理问题,并给出对应的排查和解决方案,帮助你快速定位和修复问题。
这个错误意味着 Nginx 无法成功与后端服务器通信。
常见原因包括:
后端服务未启动
后端监听端口不正确
请求被防火墙或 SELinux 拦截
后端处理超时未返回响应
解决方案是:
确认后端服务已经运行
使用 curl 或 telnet 测试后端端口是否通畅
在 Nginx 中加大连接超时时间,比如:
proxy_connect_timeout 60s;
proxy_read_timeout 120s;
使用 proxy_pass 时路径拼接规则容易出错,尤其是当 location 带 / 而 proxy_pass 也带路径时,可能造成重复路径。
错误示例:
location /api/ {
proxy_pass http://localhost:5000/api/;
}
如果用户请求的是 /api/user,最终转发给后端的会变成 /api/api/user,路径错乱。
正确写法应为:
location /api/ {
proxy_pass http://localhost:5000/;
}
记住:location 有斜杠时,proxy_pass 尾部是否加 / 会影响路径拼接。
Nginx 默认会以自身身份向后端发起请求,因此后端看到的 IP 是 Nginx 的地址,而不是客户端的真实 IP。
可以通过添加以下配置将真实 IP 传递给后端:
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
当前端通过 JavaScript 发起跨域请求时,Nginx 如果没有设置相关响应头,浏览器会阻止响应内容。
可通过以下配置允许跨域:
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET, POST, OPTIONS;
add_header Access-Control-Allow-Headers Content-Type, Authorization;
预检请求还需要处理 OPTIONS:
location /api/ {
if ($request_method = 'OPTIONS') {
add_header Content-Length 0;
add_header Content-Type text/plain;
return 204;
}
proxy_pass http://backend:5000;
}
WebSocket 是基于 HTTP 协议升级的一种连接方式,需要特殊的头部支持。
配置如下:
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
如果上传文件较大或请求体超出限制,Nginx 会报 413 Request Entity Too Large。
默认限制只有 1MB,解决办法是设置更大的上传限制:
client_max_body_size 50M;
某些后端框架返回的跳转链接是绝对路径,导致客户端跳转时直接绕过了 Nginx。
解决方案:
proxy_redirect off;
proxy_set_header Host $host;
配置 HTTPS 时,若证书路径错误或权限不对,可能导致 Nginx 无法启动或 TLS 握手失败。
排查重点:
证书路径是否正确
证书文件是否可被 Nginx 读取
是否使用 nginx -t 验证语法是否正确
当文件较大时,下载过程中中断或卡住,通常是由于超时时间或缓冲区配置不合理造成的。
建议关闭缓冲,并加大超时时间:
proxy_buffering off;
proxy_read_timeout 600s;
增加缓冲区:
proxy_buffers 16 64k;
proxy_busy_buffers_size 128k;
可能是因为:
请求中带有 Authorization 或 Cookie
缓存路径没命中
响应状态码未配置缓存策略
示例配置:
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=my_cache:10m inactive=60m max_size=1g;
location /api/ {
proxy_cache my_cache;
proxy_cache_valid 200 10m;
}
Nginx 的反向代理虽然配置灵活,但细节众多,任何一个字段出错都可能引发故障。理解这些常见问题的根本原因,并掌握排查技巧,是写好稳定代理配置的关键一步。
非著名程序员,全栈开发工程师,长期专注系统开发与架构设计。
功能待开通!
nginx服务器返回200但是浏览器报错 net::ERR_INCOMPLETE_CHUNKED_ENCODING 原因是nginx在获得后端服务器返回数据时,数据过大需要存在临时文件中,但是当前运行nginx用户,没有该文件的读写权限 导致的。 如何证实 可以查看nginx的日志,会有以下类似错误 2018/03/22 16:11:35 [crit] 9519#0: *339625 open() "/var/lib/nginx/tmp/fastcgi/5/02/0000000025" failed 很明显,nginx无法写/var/lib/nginx/tmp/fastcgi/5/02/000
模式 含义 location = /uri = 表示精确匹配只有完全相等才会匹配成功 location ^~ /uri ^~ 表示对路由进行前缀匹配 location ~ /uri ~ 表示对路由进行正则匹配 location ~* /uri ~* 表示对路由进行不区分大小写的正则匹配 location /uri 不带任何修饰符也表示前缀匹配 location / 默认匹配,任何没有匹配到的uri 多个 location 配置的情况下匹配顺序为(匹配到某一等级就结束,同一规则时匹配长度长的优先): 首先精确匹配 = 其次前缀匹配 ^~ 其次是按文件中顺
推荐日志配置 log_format main 'remote_addr=[$remote_addr] http_x_forward=[$http_x_forwarded_for] time=[$time_local] request=[$request] ' 'status=[$status] byte=[$bytes_sent] elapsed=[$request_time] upstream_connect_time=[$upstream_connect_time] upstream_response_time=[$upstream_response_time] '
stream { log_format proxy 'time=[$time_local] remote_addr=[$remote_addr]' ' protocol=[$protocol] status=[$status] byte_send=[$bytes_sent] byte_received=[$bytes_received] ' 'session_time=[$session_time] upstream_addr=[$upstream_addr] ' 'upstream_
问题 nginx 启动后 error 日志里报错,并且 https 无法访问,报错如下 "ssl_certificate" is defined in server listening on SSL port while SSL handshaking, client: 100.120.198.130, server: 0.0.0.0:443 我们需要修改下 nginx conf 配置,在 listen 443 中添加 default_server server { listen 443 ssl; # 报错配置 listen 443 default_server ssl; #