在 Linux 或 Windows 下部署 ASP.NET Core 应用 时,通常使用 Kestrel 作为内置 Web 服务器,再通过 Nginx 做反向代理。
虽然官方文档推荐这种组合,但在实际操作中,常会遇到各种问题。本文记录我遇到的问题与解决方案。
一、基本配置回顾
1️⃣ Kestrel 启动示例(Program.cs)
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(options =>
{
options.ListenAnyIP(5000); // Kestrel 监听 5000 端口
});
var app = builder.Build();
app.MapGet("/", () => "Hello World");
app.Run();
2️⃣ Nginx 反向代理配置示例
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
✅ 这是最基本的反向代理配置。
二、常见问题及解决方法
问题 1:访问 Nginx 显示 502 Bad Gateway
原因分析:
- Kestrel 未启动或端口未监听
- 防火墙阻止 5000 端口
- Nginx 配置的
proxy_pass地址错误
解决方法:
- 确认 Kestrel 启动:
netstat -tulnp | grep 5000
- 确认防火墙允许端口:
sudo ufw allow 5000/tcp
- 检查 Nginx 配置语法并重启:
sudo nginx -t
sudo systemctl restart nginx
问题 2:HTTP 1.1 WebSocket 升级失败
原因分析:
- WebSocket 需要
Upgrade和Connection头 - Nginx 默认可能未转发这些头
解决方法:
在 Nginx 配置中加入:
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
问题 3:HTTPS 配置问题
- Kestrel 通常监听 HTTP(5000)
- Nginx 负责 HTTPS 终止
- 如果直接用 HTTPS 到 Kestrel,证书配置可能复杂
解决方案:
- Kestrel 只监听 HTTP
- Nginx 配置 SSL 证书,并转发 HTTP 请求到 Kestrel
示例:
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/ssl/certs/example.crt;
ssl_certificate_key /etc/ssl/private/example.key;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
问题 4:获取客户端真实 IP
原因分析:
- Kestrel 看到的都是 Nginx 的 IP
- 需要使用
X-Forwarded-For头
解决方法:
在 Program.cs 中添加:
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
并确保 Nginx 配置了:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
问题 5:大文件上传失败或超时
原因分析:
- Nginx 默认
client_max_body_size为 1M - Kestrel 也有请求大小限制
解决方法:
- 修改 Nginx 配置:
server {
...
client_max_body_size 50M;
}
- 修改 Kestrel 配置:
builder.WebHost.ConfigureKestrel(options =>
{
options.Limits.MaxRequestBodySize = 50 * 1024 * 1024; // 50MB
});
三、部署优化建议
- 使用 Systemd 管理 Kestrel 服务
sudo nano /etc/systemd/system/kestrel-app.service
示例 Service 文件:
[Unit]
Description=Kestrel .NET App
After=network.target
[Service]
WorkingDirectory=/var/www/myapp
ExecStart=/usr/bin/dotnet /var/www/myapp/MyApp.dll
Restart=always
RestartSec=10
SyslogIdentifier=kestrel-app
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
[Install]
WantedBy=multi-user.target
- 开启 Nginx 缓存或压缩
- 减少静态资源传输
- 提升访问速度
- 日志监控
- Kestrel 日志:
dotnet MyApp.dll --urls http://*:5000 - Nginx 日志:
/var/log/nginx/access.log和/var/log/nginx/error.log
- Kestrel 日志:
四、总结
配置 Kestrel + Nginx 反向代理虽然官方推荐,但实际部署过程中常见问题包括:
| 问题 | 原因 | 解决方法 |
|---|---|---|
| 502 Bad Gateway | Kestrel 未启动 / Nginx 配置错误 | 检查端口、重启服务 |
| WebSocket 升级失败 | Upgrade/Connection 头未转发 | Nginx 配置 proxy_set_header |
| HTTPS 配置复杂 | Kestrel 直接 HTTPS 不方便 | 让 Nginx 终止 SSL |
| 客户端真实 IP 不可见 | 未使用 X-Forwarded-For | 配置 ForwardedHeaders 中间件 |
| 大文件上传失败或超时 | Nginx & Kestrel 限制 | 增加 client_max_body_size & MaxRequestBodySize |
正确配置后,Kestrel + Nginx 能提供 高性能、稳定、安全的 .NET Core Web 服务。