部署与运维

Nginx 配置与排障:请求路径、代理语义和变更验证

Nginx 常位于静态站点和后端应用之前。配置出错时,先确定请求匹配了哪个 server 与 location,再检查 URI 转发、上游连接和响应时间。调大连接数之前,应有证据说明瓶颈出在哪里。

Nginx 常位于静态站点和后端应用之前。配置出错时,先确定请求匹配了哪个 server 与 location,再检查 URI 转发、上游连接和响应时间。调大连接数之前,应有证据说明瓶颈出在哪里。

配置加载与变更

bash3 行
nginx -V
sudo nginx -t
sudo nginx -T

-V 显示版本和模块,-t 检查配置,-T 展开包含文件。完整配置可能含内部地址或凭据,排查记录对外共享前需要处理这些字段。

使用包管理器安装的服务通常由 systemd 管理。配置验证成功后用 sudo systemctl reload nginx 平滑加载;失败则保留当前配置并修复。重载后还需发请求检查新规则,语法正确无法证明路径、证书或后端服务正确。

先理解 URI 如何转发

以下 server 放在已有 http 块包含的站点文件中。假设后端接收 /users,前端访问 /api/users:

nginx18 行
server {
    listen 80;
    server_name example.com;
    root /srv/site;

    location /api/ {
        proxy_pass http://127.0.0.1:8080/;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_connect_timeout 5s;
        proxy_read_timeout 60s;
    }

    location / {
        try_files $uri $uri/ /index.html;
    }
}

这里 proxy_pass 包含 URI /,匹配到的 /api/ 前缀被替换,后端收到 /users。若写成 proxy_pass http://127.0.0.1:8080;,则保留原请求路径。包含变量、正则 location 或 rewrite 的情况有额外规则,详见代理模块文档。

try_files 适合前端 history 路由,但 API 请求需要单独处理,避免接口不存在时返回 index.html 并伪装成 200。example.com、目录和上游地址均为示例。

HTTPS 与 HTTP/2 的版本差异

Nginx 1.25.1 起支持独立的 http2 on 指令,旧发行版需使用相应版本语法。开启前确认编译模块及证书路径。HTTP/2 模块文档给出了指令边界。

nginx11 行
server {
    listen 443 ssl;
    http2 on;
    server_name example.com;
    ssl_certificate /etc/nginx/tls/fullchain.pem;
    ssl_certificate_key /etc/nginx/tls/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    location / {
        proxy_pass http://127.0.0.1:8080;
    }
}

客户端到 Nginx 的 HTTP/2 与 Nginx 到上游的协议配置分别生效。证书文件更新后需要确认 Nginx 已加载新证书,并从外部请求验证实际呈现的证书链。

流式接口与 WebSocket

生成式接口使用 SSE 时,可在对应 location 设置 proxy_buffering off;,并核对上游是否及时 flush。proxy_read_timeout 限制两次上游读取之间的间隔;它与完整请求总时长需要分开设计。关闭缓冲也会改变慢客户端对上游连接的占用。

WebSocket 需要显式转发升级头;以下 map 放在 http 层:

nginx4 行
map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

在 WebSocket 的 location 内设置:

nginx3 行
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;

将流式和普通下载接口分开配置,避免为一条长连接修改整个站点的缓冲与超时。

让日志回答具体问题

在 http 层定义日志格式,再对目标站点启用:

nginx5 行
log_format timing '$request_id $status $request_time '
                  '$upstream_addr $upstream_status '
                  '$upstream_connect_time $upstream_header_time '
                  '$upstream_response_time';
access_log /var/log/nginx/timing.log timing;

连接时间增长常提示上游建连或网络问题;响应头时间增长需要联查应用排队和处理;总请求时间还受客户端接收速度影响。出现重试时上游字段可能包含多个值,解析器应保留尝试顺序。

现象 检查路径
404 server/location、转发 URI、文件路径与权限
502 上游监听、连接拒绝、协议不匹配、提前关闭连接
504 上游处理、排队和各级超时预算
静态资源正常,API 返回 HTML /api/ 匹配与 SPA fallback
流式内容一次性出现 上游 flush、Nginx 与其他代理的缓冲

连接数和重试的边界

worker_connections 是每个 worker 的连接上限,上游连接也会占用连接和文件描述符。它不能直接等同于可处理用户数;还需核对文件描述符限制、内存、上游容量及长连接比例。

上游失败重试可能重复提交业务操作,涉及写入时由业务提供幂等处理。上线新路由前固定几个代表请求:静态资源、深层前端路由、API 成功与失败、长连接。记录状态码、路径和延迟;回滚后复跑同一组请求。

← 返回文章