Nginx 学习笔记(三):HTTPS、性能优化与实战

写在前面

本文是 Nginx 学习笔记系列的第三篇,聚焦生产环境实战:HTTPS 证书配置、性能优化技巧(压缩、缓存、限流、跨域),以及 .NET 应用部署和常见问题排查。


一、HTTPS 配置

1.1 为什么需要 HTTPS

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
HTTP 的问题:
  - 明文传输       — 数据可被窃听
  - 不验证身份     — 可能被冒充(钓鱼)
  - 数据可被篡改   — 运营商插广告、劫持

HTTPS = HTTP + TLS
  - 加密传输       — 数据被加密,无法窃听
  - 身份验证       — 证书验证服务器身份
  - 完整性校验     — 数据被篡改可检测
  - SEO 加分       — Google 优先收录 HTTPS

1.2 申请免费证书(Let’s Encrypt)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 安装 Certbot
sudo apt install certbot python3-certbot-nginx

# 自动获取并配置证书(一条命令搞定)
sudo certbot --nginx -d example.com -d www.example.com

# 仅获取证书(手动配置)
sudo certbot certonly --nginx -d example.com

# 手动获取(DNS 验证,适合泛域名)
sudo certbot certonly --manual --preferred-challenges dns -d "*.example.com" -d example.com
1
2
3
4
5
6
7
8
证书文件位置:
  /etc/letsencrypt/live/example.com/fullchain.pem    — 证书(含中间证书)
  /etc/letsencrypt/live/example.com/privkey.pem      — 私钥

证书有效期:90 天
自动续期:Certbot 安装时会自动创建定时任务
  查看:systemctl list-timers | grep certbot
  手动续期:sudo certbot renew --dry-run

1.3 自动续期配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 检查自动续期定时任务
systemctl status certbot.timer

# 手动测试续期(不会真的续)
sudo certbot renew --dry-run

# 续期后自动重载 Nginx(配置 hook)
# /etc/letsencrypt/renewal-hooks/post/reload-nginx.sh
#!/bin/bash
nginx -t && systemctl reload nginx

1.4 手动配置 HTTPS

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
server {
    # HTTP → HTTPS 重定向
    listen 80;
    server_name example.com www.example.com;
    return 301 https://www.example.com$request_uri;
}

server {
    listen 443 ssl http2;                   # 开启 HTTP/2
    server_name www.example.com;

    # 证书配置
    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # SSL 参数
    ssl_protocols TLSv1.2 TLSv1.3;          # 只允许 TLS 1.2 和 1.3
    ssl_ciphers HIGH:!aNULL:!MD5;           # 高强度加密套件
    ssl_prefer_server_ciphers on;           # 优先使用服务器端的加密套件

    # SSL 会话缓存
    ssl_session_cache shared:SSL:10m;       # 10MB 缓存,约 4万个会话
    ssl_session_timeout 10m;                # 会话超时 10 分钟
    ssl_session_tickets off;                # 禁用 Session Tickets(前向安全)

    # OCSP Stapling(在线证书状态检查)
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;

    # HSTS(告诉浏览器只能用 HTTPS 访问)
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    # 安全头部
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    root /var/www/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

1.5 SSL 安全等级测试

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 用 SSL Labs 测试(在线)
# https://www.ssllabs.com/ssltest/

# 用 openssl 测试连接
openssl s_client -connect example.com:443 -servername example.com

# 测试支持的协议
openssl s_client -connect example.com:443 -tls1_2
openssl s_client -connect example.com:443 -tls1_3

# 查看证书信息
openssl x509 -in /etc/letsencrypt/live/example.com/fullchain.pem -text -noout

1.6 自签名证书(开发环境)

1
2
3
4
5
6
# 生成自签名证书
openssl req -x509 -nodes -days 365 \
  -newkey rsa:2048 \
  -keyout selfsigned.key \
  -out selfsigned.crt \
  -subj "/CN=localhost"
1
2
3
4
5
6
7
server {
    listen 443 ssl;
    server_name localhost;

    ssl_certificate     /etc/nginx/ssl/selfsigned.crt;
    ssl_certificate_key /etc/nginx/ssl/selfsigned.key;
}

二、性能优化

2.1 gzip 压缩

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
http {
    # 开启 gzip
    gzip on;
    gzip_vary on;                           # 添加 Vary: Accept-Encoding 头
    gzip_proxied any;                       # 代理请求也压缩
    gzip_comp_level 4;                      # 压缩级别 1-9(4 是最佳平衡点)
    gzip_min_length 256;                    # 小于 256 字节不压缩
    gzip_buffers 16 8k;                     # 压缩缓冲区
    gzip_http_version 1.1;                  # 最低 HTTP 版本
    gzip_types
        text/plain
        text/css
        text/xml
        text/javascript
        application/javascript
        application/json
        application/xml
        application/rss+xml
        application/atom+xml
        image/svg+xml
        font/opentype
        font/ttf
        font/woff2
        application/wasm;
}
1
2
3
4
5
6
7
8
9
压缩效果对比:
  未压缩 HTML(50KB)→ gzip 后(~8KB)   减少 84%
  未压缩 CSS(100KB)→ gzip 后(~15KB)  减少 85%
  未压缩 JS(200KB) → gzip 后(~50KB)  减少 75%

注意:
  - 图片(jpg/png/gif)和视频已经压缩过,不要再 gzip
  - gzip_comp_level 不是越高越好,6 以上 CPU 开销增大但压缩收益递减
  - 推荐值 4-6

2.2 Brotli 压缩(比 gzip 更好)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 需要安装 ngx_brotli 模块
# Docker 可用 nginx:1.26-alpine 自行编译或使用 openresty

http {
    brotli on;
    brotli_comp_level 6;
    brotli_types text/plain text/css application/javascript application/json;

    # 同时支持 gzip 和 brotli
    # Nginx 会根据客户端 Accept-Encoding 自动选择
    gzip on;
    gzip_comp_level 4;
}
1
2
3
4
5
Brotli vs gzip:
  Brotli 通常比 gzip 多压缩 15-25%
  但压缩速度比 gzip 慢(CPU 开销更大)
  大多数现代浏览器都支持
  建议静态资源预压缩用 Brotli,动态内容用 gzip

2.3 浏览器缓存

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
server {
    root /var/www/html;

    # 静态资源 — 长期缓存
    location ~* \.(css|js)$ {
        expires 1y;                         # 1 年
        add_header Cache-Control "public, immutable";
        # immutable:告诉浏览器不需要重新验证
    }

    # 图片 — 中期缓存
    location ~* \.(jpg|jpeg|png|gif|ico|svg|webp|avif)$ {
        expires 6M;                         # 6 个月
        add_header Cache-Control "public";
    }

    # 字体 — 长期缓存
    location ~* \.(woff|woff2|ttf|otf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    # HTML — 不缓存或短缓存
    location ~* \.html$ {
        add_header Cache-Control "no-cache";
        # no-cache:每次都验证(304 Not Modified)
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
缓存策略总结:
  文件类型           策略              时间
  ──────────────────────────────────────────
  HTML              no-cache          每次验证
  CSS/JS(带hash)   immutable         1 年
  图片               public            6 个月
  字体               immutable         1 年
  API 响应           no-store          不缓存

  带 hash 的文件名(app.3a4b5c.js)→ 可以永久缓存
  不带 hash 的文件名(app.js)    → 不能长期缓存

2.4 限流

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
http {
    # 基于 IP 的请求速率限制
    # binary_remote_addr:二进制格式的 IP,占用更少内存
    # zone=api_limit:10m:共享内存区域,10MB(约 16万个 IP)
    # rate=100r/s:每个 IP 每秒 100 个请求
    limit_req_zone $binary_remote_addr zone=api_limit:10m rate=100r/s;

    # 基于IP的并发连接数限制
    limit_conn_zone $binary_remote_addr zone=conn_limit:10m;

    server {
        # 请求速率限制
        location /api/ {
            limit_req zone=api_limit burst=50 nodelay;
            # burst=50:允许短时突发 50 个请求
            # nodelay:突发请求不延迟处理

            proxy_pass http://backend;
        }

        # 并发连接限制
        location /download/ {
            limit_conn conn_limit 10;        # 每个 IP 最多 10 个并发连接
            limit_rate 500k;                 # 每个连接限速 500KB/s
        }

        # 限流后的自定义响应
        limit_req_status 429;                # 返回 429 Too Many Requests
        limit_conn_status 429;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
限流参数说明:
  rate=10r/s    — 每秒 10 个请求
  rate=600r/m   — 每分钟 600 个请求(更适合 API)

  burst=N       — 允许排队的请求数
  nodelay       — 突发请求立即处理(不延迟)

  不加 burst:
    超过 rate 立即返回 429
  加 burst + nodelay:
    允许瞬时突发,但总速率不超过 rate

2.5 跨域(CORS)配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
server {
    # CORS 配置
    location /api/ {
        # 允许的源
        add_header Access-Control-Allow-Origin "https://www.example.com" always;

        # 允许的方法
        add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;

        # 允许的头部
        add_header Access-Control-Allow-Headers "Authorization, Content-Type, X-Requested-With" always;

        # 允许携带凭证(Cookie)
        add_header Access-Control-Allow-Credentials "true" always;

        # 预检请求缓存时间
        add_header Access-Control-Max-Age 3600 always;

        # 处理 OPTIONS 预检请求
        if ($request_method = 'OPTIONS') {
            add_header Access-Control-Allow-Origin "https://www.example.com" always;
            add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
            add_header Access-Control-Allow-Headers "Authorization, Content-Type" always;
            add_header Access-Control-Max-Age 3600 always;
            add_header Content-Length 0;
            add_header Content-Type text/plain;
            return 204;
        }

        proxy_pass http://backend;
    }
}
1
2
3
4
5
6
7
8
9
CORS 要点:
  Access-Control-Allow-Origin:
    - 只能设置一个源,不能设置多个
    - 动态设置可以用 $http_origin 变量(但需维护白名单)

  预检请求(OPTIONS):
    - 浏览器自动发送
    - 必须正确响应,否则实际请求不会发出
    - 非简单请求(带自定义头、PUT/DELETE 等)会触发预检

2.6 动态 CORS(多域名白名单)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 定义允许的域名
map $http_origin $cors_origin {
    default "";
    "https://www.example.com"    "https://www.example.com";
    "https://app.example.com"    "https://app.example.com";
    "https://admin.example.com"  "https://admin.example.com";
    "http://localhost:3000"      "http://localhost:3000";
}

server {
    location /api/ {
        # 动态设置 CORS
        add_header Access-Control-Allow-Origin $cors_origin always;
        add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
        add_header Access-Control-Allow-Headers "Authorization, Content-Type" always;

        if ($cors_origin = "") {
            return 403;                    # 不在白名单的源直接拒绝
        }

        if ($request_method = 'OPTIONS') {
            add_header Access-Control-Allow-Origin $cors_origin always;
            add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
            add_header Access-Control-Max-Age 3600 always;
            return 204;
        }

        proxy_pass http://backend;
    }
}

三、.NET 应用部署实战

3.1 部署架构

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
客户端 → Nginx(443/80)→ .NET 应用(5000)

Nginx 负责:
  ✓ HTTPS 终端(.NET 应用不需要处理 TLS)
  ✓ 静态文件服务(wwwroot)
  ✓ 压缩、缓存
  ✓ 限流、安全
  ✓ 负载均衡(多实例)

.NET 应用负责:
  ✓ API 处理
  ✓ 业务逻辑
  ✓ SSR(Blazor Server / Razor Pages)

3.2 发布 .NET 应用

1
2
3
4
5
6
7
8
# 发布应用
dotnet publish -c Release -o /app/publish

# 运行
cd /app/publish
./MyApp --urls http://0.0.0.0:5000

# 推荐用 systemd 管理

3.3 systemd 服务配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# /etc/systemd/system/myapp.service
[Unit]
Description=My .NET Application
After=network.target

[Service]
Type=notify
WorkingDirectory=/app/publish
ExecStart=/app/publish/MyApp --urls http://0.0.0.0:5000
Restart=always
RestartSec=10
SyslogIdentifier=myapp
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=ASPNETCORE_URLS=http://0.0.0.0:5000
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false

[Install]
WantedBy=multi-user.target
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 启用并启动
sudo systemctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp

# 查看状态
sudo systemctl status myapp

# 查看日志
sudo journalctl -u myapp -f

3.4 Nginx 配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# /etc/nginx/conf.d/myapp.conf

# HTTP → HTTPS 重定向
server {
    listen 80;
    server_name api.example.com;
    return 301 https://$host$request_uri;
}

# HTTPS
server {
    listen 443 ssl http2;
    server_name api.example.com;

    # SSL 证书
    ssl_certificate     /etc/letsencrypt/live/api.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;

    # SSL 参数
    include /etc/nginx/snippets/ssl-params.conf;

    # 安全头部
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Strict-Transport-Security "max-age=31536000" always;

    # 请求体大小
    client_max_body_size 50m;

    # API 请求转发到 .NET
    location /api/ {
        proxy_pass http://127.0.0.1:5000;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        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_connect_timeout 5s;
        proxy_send_timeout 30s;
        proxy_read_timeout 30s;
    }

    # Swagger(仅开发/测试环境)
    location /swagger/ {
        proxy_pass http://127.0.0.1:5000/swagger/;
    }

    # 健康检查
    location /health {
        access_log off;
        proxy_pass http://127.0.0.1:5000/health;
    }
}

3.5 ASP.NET Core 配合 Nginx

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Program.cs
var builder = WebApplication.CreateBuilder(args);

// 配置转发头(必须在使用路径基之前)
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders = ForwardedHeaders.XForwardedFor
                            | ForwardedHeaders.XForwardedProto;
    options.KnownNetworks.Clear();
    options.KnownProxies.Clear();
});

var app = builder.Build();

// 必须在其他中间件之前调用
app.UseForwardedHeaders();

// 其他中间件
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();

app.Run();
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// appsettings.json
{
  "Urls": "http://0.0.0.0:5000",
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://0.0.0.0:5000"
      }
    },
    "Limits": {
      "MaxRequestBodySize": 52428800
    }
  }
}
1
2
3
4
关键配置:
  UseForwardedHeaders()  — 让 ASP.NET Core 读取 X-Forwarded-* 头
  KnownNetworks.Clear()  — 信任所有代理(按需限制)
  Kestrel 只监听 HTTP    — HTTPS 由 Nginx 处理

3.6 Docker Compose 部署

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
version: '3.8'

services:
  myapp:
    image: myapp:latest
    container_name: myapp
    environment:
      - ASPNETCORE_ENVIRONMENT=Production
      - ASPNETCORE_URLS=http://0.0.0.0:5000
    expose:
      - "5000"
    restart: always
    networks:
      - internal

  nginx:
    image: nginx:1.26
    container_name: nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/conf:/etc/nginx
      - ./nginx/ssl:/etc/nginx/ssl
      - ./nginx/logs:/var/log/nginx
    depends_on:
      - myapp
    restart: always
    networks:
      - internal

networks:
  internal:
    internal: true        # 内部网络,不对外暴露
1
2
3
4
5
好处:
  - myapp 只在内部网络,外部无法直接访问
  - Nginx 是唯一的入口
  - 升级 myapp 不影响 Nginx
  - 可以轻松扩展 myapp 实例

四、常见问题排查

4.1 502 Bad Gateway

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
原因:Nginx 无法连接到后端服务

排查步骤:
  1. 检查后端是否运行
     systemctl status myapp
     curl http://127.0.0.1:5000/health

  2. 检查端口是否正确
     ss -tlnp | grep 5000

  3. 检查防火墙
     sudo iptables -L -n

  4. 查看 Nginx 错误日志
     tail -f /var/log/nginx/error.log
     # 常见错误:
     # connect() failed (111: Connection refused)
     # connect() failed (113: No route to host)

4.2 504 Gateway Timeout

1
2
3
4
5
6
7
8
原因:后端响应超时

解决:
  # 增加超时时间
  proxy_read_timeout 120s;        # 默认 60s,慢接口可以增大
  proxy_connect_timeout 10s;

  # 或者优化后端性能

4.3 413 Request Entity Too Large

1
2
3
4
原因:请求体超过限制

解决:
  client_max_body_size 50m;       # 默认 1m,按需调大

4.4 配置不生效

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 检查配置语法
nginx -t

# 重新加载配置
nginx -s reload

# 检查是否加载了正确的配置文件
nginx -T | grep "configuration file"
# 确认 include 路径是否正确

# 检查是否有缓存
curl -H "Cache-Control: no-cache" http://localhost

4.5 权限问题

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
常见错误:403 Forbidden

排查:
  1. 检查文件权限
     ls -la /var/www/html/
     # Nginx 用户(www-data)需要读取权限

  2. 检查 SELinuxCentOS/RHEL
     getenforce
     # 如果是 Enforcing,需要设置上下文
     chcon -R -t httpd_sys_content_t /var/www/html/

  3. 检查 user 指令
     # nginx.conf 中的 user 是否有权限访问文件
     user www-data;

4.6 性能排查

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# 查看 Nginx 状态(需要 stub_status 模块)
location /nginx_status {
    stub_status;
    access_log off;
    allow 127.0.0.1;
    deny all;
}

# 访问状态
curl http://localhost/nginx_status
# Active connections: 5
# server accepts handled requests
#  10 10 100
# Reading: 0 Writing: 1 Waiting: 4

# 分析访问日志(慢请求)
awk '$NF > 1 {print $0}' /var/log/nginx/access.log | sort -kNF -rn | head -20

# 查看 Nginx 进程状态
ps aux | grep nginx
top -p $(pgrep nginx | tr '\n' ',')

五、生产环境检查清单

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# ✅ 一个完整的生产级配置模板
server {
    listen 443 ssl http2;
    server_name example.com;

    # --- SSL ---
    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    ssl_stapling on;
    ssl_stapling_verify on;

    # --- 安全头部 ---
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    # --- 性能 ---
    gzip on;
    gzip_vary on;
    gzip_min_length 256;
    gzip_comp_level 4;
    gzip_types text/plain text/css application/javascript application/json;

    # --- 安全 ---
    client_max_body_size 50m;
    server_tokens off;                     # 隐藏 Nginx 版本号

    # --- 代理 ---
    location / {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        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;
    }
}

# HTTP → HTTPS
server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}

六、小结

本文学习了 Nginx 生产环境实战:

  • HTTPS 配置(Let’s Encrypt、手动配置、安全参数)
  • SSL 安全优化(HSTS、OCSP Stapling、安全头部)
  • 性能优化(gzip、Brotli、浏览器缓存、限流)
  • CORS 跨域配置(静态和动态白名单)
  • .NET 应用部署(systemd、Docker Compose)
  • ASP.NET Core 配合 Nginx(ForwardedHeaders)
  • 常见问题排查(502、504、413、权限、性能)
  • 生产环境配置检查清单

下一篇将深入 Nginx 的底层原理:进程模型、事件驱动机制、请求处理流程和内存管理。