Nginx 反向代理与负载均衡实战笔记
Words: 860Read Time: 3 minLast edited: 2026-8-4
我的博客是 ASP.NET Core 写的,Kestrel 自己监听 5000 端口。让 Kestrel 直接对公网不是不行,但前面挡一层 Nginx 是更常见的做法:静态文件、HTTPS、负载均衡都能交给它。这篇是我配置反代和简单负载均衡的实战记录,附带一份 502 排查清单。
为什么是 Nginx
Kestrel 是个很能打的应用服务器,但它的定位是"应用内部"的服务器。把 Nginx 放在前面有几个直接的好处:
- 静态文件(css、js、图片)由 Nginx 直接返回,不用惊动 .NET 进程
- HTTPS 证书统一在 Nginx 层管理,应用只跑 HTTP
- 以后要加第二个站点、做分流、限流,都是改配置的事
- 应用重启或部署时,Nginx 层还能做点缓冲
架构很简单:公网请求打到 Nginx 的 80/443,Nginx 再转发给本机
127.0.0.1:5000 的 Kestrel。反向代理配置
在
/etc/nginx/conf.d/ 下新建 myblog.conf:proxy_set_header 这几行是关键,一个都不能少:- Host:原始域名。不传的话,后端拿到的 Host 是
127.0.0.1:5000,生成跳转链接时会带上内网地址,直接社死
- X-Forwarded-For:真实客户端 IP。不传的话,.NET 里
RemoteIpAddress拿到的全是127.0.0.1,访问统计和限流全废
- X-Forwarded-Proto:原始协议(http/https),做 HTTPS 跳转和生成完整链接时会用到
.NET 侧记得启用 ForwardedHeaders 中间件,否则这些头传了也白传。改完配置先
sudo nginx -t 检查语法,再 sudo systemctl reload nginx,平滑生效不断连接。顺手试试负载均衡
为了验证 Nginx 的 upstream 能力,我把应用起了两个实例:5000 和 5001,然后配置轮询:
默认就是轮询(round-robin),请求会交替打到两个实例。我特意 kill 掉其中一个实例测试:Nginx 会把失败的节点临时摘掉(max_fails 机制),请求全部流向活着的实例,页面上完全无感。这就是最朴素的高可用。当然,我的博客实际没有这种并发量,配这个纯属学习,但理解原理很有必要。
502 排查清单
配反代后最常遇到的就是 502 Bad Gateway,我总结的排查顺序:
- 后端活着吗:
curl http://127.0.0.1:5000直接打后端,不通就是应用挂了或端口不对,ss -tlnp | grep 5000确认监听状态
- SELinux 和防火墙:CentOS 上 SELinux 默认禁止 Nginx 连后端端口,经典大坑,日志里会有 permission denied
- 看错误日志:
/var/log/nginx/error.log,connect() failed 后面跟的原因基本能直接定位问题
- upstream 全挂:负载均衡场景下所有后端都死,Nginx 也会直接 502
我自己的一次 502 经历:改了应用配置后重启,systemd 里 ExecStart 路径写错了,应用根本没起来,我却盯着 Nginx 配置查了半小时。教训就是——先 curl 后端,先 curl 后端,先 curl 后端。
Loading...