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,我总结的排查顺序:
  1. 后端活着吗curl http://127.0.0.1:5000 直接打后端,不通就是应用挂了或端口不对,ss -tlnp | grep 5000 确认监听状态
  1. SELinux 和防火墙:CentOS 上 SELinux 默认禁止 Nginx 连后端端口,经典大坑,日志里会有 permission denied
  1. 看错误日志/var/log/nginx/error.log,connect() failed 后面跟的原因基本能直接定位问题
  1. upstream 全挂:负载均衡场景下所有后端都死,Nginx 也会直接 502
我自己的一次 502 经历:改了应用配置后重启,systemd 里 ExecStart 路径写错了,应用根本没起来,我却盯着 Nginx 配置查了半小时。教训就是——先 curl 后端,先 curl 后端,先 curl 后端。
Loading...
© 2024 - 2026 ihuadz
中文