3.4 Nginx Web 服务器配置与管理

预计阅读时间:18 分钟

📖 目录

学习目标

学完本章后,你将能够:

  • 理解 Nginx 事件驱动架构及其与 Apache 的差异
  • 配置虚拟主机(server block)和 location 匹配规则
  • 搭建反向代理和负载均衡
  • 配置 HTTPS、gzip、缓存和限流
  • 运用 Nginx 运维命令诊断和重载配置

核心知识

  • Nginx——高性能 HTTP 服务器和反向代理服务器,以事件驱动、异步非阻塞架构著称
  • 虚拟主机(Server Block)——在同一 Nginx 实例上,通过 server_name 区分不同域名
  • Location 匹配——根据 URI 路径,用前缀匹配或正则匹配指定不同的处理规则
  • 反向代理(Reverse Proxy)——Nginx 接收客户端请求,转发到后端服务器,再将响应返回客户端
  • 负载均衡(Load Balancing)——通过 upstream 模块将请求分发到多台后端服务器
  • Worker 进程——Nginx 的工作进程,每个 worker 独立处理连接,数量通常等于 CPU 核心数
  • 事件驱动(Event-Driven)——Nginx 不按连接分配线程,而是通过事件循环处理所有连接

知识关联

原理讲解

事件驱动架构:Nginx 为什么这么快?

传统的 Web 服务器(如 Apache 的 prefork 模式)为每个连接分配一个进程或线程。当并发连接数上升时,线程切换和内存开销急剧增加。Nginx 采用 事件驱动(event-driven) 模型:一个 worker 进程可以同时处理数千个连接,通过非阻塞 I/O 和事件通知(epoll / kqueue)实现高并发低内存。

特性NginxApache(prefork)
架构事件驱动、异步进程/线程每连接
并发模型一个 worker 处理数千连接每个连接一个进程
静态文件极快(直接 sendfile)一般
动态内容通过反向代理转发内嵌模块直接处理
配置语法简洁、层级化.htaccess 每目录覆盖

请求处理流程

Nginx 处理一个请求的典型路径:接收 HTTP 请求 → 根据 server_name 匹配虚拟主机 → 根据 URI 匹配 location → 执行对应处理(serve 静态文件、proxy_pass 转发等)→ 返回响应。location 匹配有严格的优先级:精确匹配 = > 前缀匹配 ^~ > 正则匹配 ~ > 普通前缀匹配。

master/worker 进程模型

Nginx 启动后产生两类进程:一个 master 进程和多个 worker 进程。master 不处理业务请求,只负责:读取和校验配置、fork/回收 worker、平滑重载(reload 时新 worker 拉起、旧 worker 处理完存量连接后退出)。worker 进程数通常等于 CPU 核心数,每个 worker 内部用事件循环(epoll)处理数千个连接,worker 之间通过共享内存(如 upstream 连接统计、SSL 会话缓存)协作。

# 查看进程结构
ps -ef | grep nginx
# 输出:
# root      1234     1  0  master process nginx        ← master(root 运行)
# www-data  1235  1234  0  worker process              ← worker(www-data 运行,Debian/Ubuntu 默认)
# www-data  1236  1234  0  worker process
# www-data  1237  1234  0  worker process

# worker 数量配置(nginx.conf)
worker_processes auto;        # 自动等于 CPU 核心数
worker_connections 1024;      # 每个 worker 最大并发连接数(含 keepalive)

# 查看实际 worker 数
cat /proc/cpuinfo | grep processor | wc -l
为什么 nginx -s reload 不断线?

master 收到 reload 信号后,用新配置 fork 出新 worker 并逐步接管新连接,旧 worker 在完成已接受的连接后优雅退出——整个过程对客户端透明。因此生产环境修改配置后应使用 reload 而非 restart

为什么 Nginx 用 master/worker 模型而不是多线程?

传统 Web 服务器(如 Apache)为每个连接分配一个线程或进程。Nginx 的 master/worker 模型是完全不同的设计哲学:一个 worker 进程通过事件循环处理数千个连接,而不是为每个连接创建新线程。这背后是操作系统 I/O 模型的演进——Linux 的 epoll(以及 BSD 的 kqueue)允许一个进程同时监听大量文件描述符,只有真正有数据到达的连接才会被处理,空闲连接几乎不消耗 CPU。

这种设计的优势:线程切换的开销在高并发下会成为瓶颈(每次上下文切换约 1-10 微秒,10 万并发意味着频繁切换),而事件驱动模型完全没有这个问题。Nginx 的单个 worker 可以轻松处理 1 万+ 并发连接,内存占用仅几 MB,而 Apache 的 prefork 模式在 1 万并发时需要 1 万个进程,内存消耗可达数 GB。

master/worker 分离的意义:master 以 root 权限运行(绑定 80/443 端口、读取配置),worker 以低权限用户运行(处理请求)。即使某个 worker 被攻破,攻击者也拿不到 root 权限。

Nginx vs Apache:为什么高并发场景选 Nginx?

维度NginxApache
架构事件驱动,单进程处理数千连接进程/线程每连接,需大量内存
静态文件性能极快(sendfile + aio)一般(受模块影响)
动态内容反向代理到 PHP-FPM/应用服务器mod_php 直接内嵌处理
配置方式全局配置 + server/location 块.htaccess 允许目录级覆盖(灵活但性能差)
内存占用低(每连接仅文件描述符)高(每连接一个线程/进程栈空间)
适用场景反向代理、负载均衡、静态文件、高并发PHP 内嵌、需要 .htaccess 的共享主机

选型结论:如果是纯反向代理或静态文件服务器,Nginx 无悬念胜出。如果需要在 Web 服务器内直接运行 PHP(mod_php),Apache 的集成度更好。现代架构中,Nginx 做前端代理 + 后端应用服务器(PHP-FPM、Node.js、Go)的组合是最主流的方案。

事件驱动模型:epoll 如何工作?

epoll 的核心思想是就绪通知:程序注册一批文件描述符到 epoll 实例,然后调用 epoll_wait 阻塞等待。当某个 fd 上有数据到达时,内核将其标记为就绪并唤醒进程。与传统的 select/poll 相比,epoll 不需要每次都遍历所有 fd——它通过回调机制在 fd 就绪时直接加入就绪列表,时间复杂度从 O(N) 降到 O(1)。这就是为什么 Nginx 即使管理 10 万个连接,worker 的 CPU 开销仍然很低。

worker 连接数上限速算

单机 Nginx 的理论并发连接数 ≈ worker_processes × worker_connections。例如 4 核 CPU、worker_connections 1024,则约可承载 4096 个并发连接(一个连接对应一个客户端请求;若启用 keepalive,一个浏览器可能占用多个连接)。超出上限时 error.log 会出现 worker_connections are not enough,此时优先排查是否有连接泄漏,而非盲目调大数值。

示例代码

1. 安装与基本配置结构

# 安装 Nginx
sudo apt update && sudo apt install nginx -y

# 启动并设置开机自启
sudo systemctl enable --now nginx

# 验证服务状态
sudo systemctl status nginx
# 输出: ● nginx.service - A high performance web server and a reverse proxy server
#        Active: active (running)

# Nginx 关键目录结构
# /etc/nginx/
#   ├── nginx.conf           # 主配置文件
#   ├── sites-available/     # 可用站点配置
#   ├── sites-enabled/       # 已启用站点(符号链接到 sites-available)
#   └── conf.d/              # 额外配置片段
# /var/www/                  # 默认网站根目录
# /var/log/nginx/
#   ├── access.log           # 访问日志
#   └── error.log            # 错误日志

2. 配置虚拟主机(Server Block)

# /etc/nginx/sites-available/example.com
server {
    listen 80;
    server_name example.com www.example.com;

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

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

    # 启用 gzip 压缩(也可放在 http 块中全局生效)
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml;
    gzip_min_length 1000;
}

# 启用站点(创建符号链接)
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t          # 测试配置
sudo systemctl reload nginx  # 重载

3. 反向代理

# 将 /api/ 路径的请求转发到后端应用
server {
    listen 80;
    server_name api.example.com;

    location /api/ {
        proxy_pass http://localhost:3000;
        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 30;
        proxy_read_timeout 60;
    }

    # 拒绝访问 . 开头的隐藏文件
    location ~ /\. {
        deny all;
    }
}

4. 负载均衡

# 定义后端服务器池
upstream backend {
    # 负载均衡算法:least_conn(最少连接)、ip_hash(会话保持)、默认轮询
    least_conn;

    server 192.168.1.10:3000 weight=3;   # 权重 3,承担更多请求
    server 192.168.1.11:3000 weight=1;
    server 192.168.1.12:3000 backup;     # 备用服务器
}

server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://backend;
        proxy_set_header Host $host;
    }
}

# 健康检查(需 nginx-plus 或单独工具):
# upstream 中的 server 会自动做被动健康检查
# 若连续失败则标记为不可用

5. HTTPS 配置

# 第一步:使用 certbot 获取证书(Let's Encrypt)
# sudo apt install certbot python3-certbot-nginx -y
# sudo certbot --nginx -d example.com -d www.example.com

# 第二步:Nginx HTTPS 配置
server {
    listen 443 ssl http2;
    server_name example.com;

    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 ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers on;

    # HSTS(告诉浏览器始终用 HTTPS)
    add_header Strict-Transport-Security "max-age=63072000" always;

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

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

6. 缓存与限流

# 缓存配置
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mycache:10m max_size=1g;

server {
    location / {
        proxy_cache mycache;
        proxy_cache_valid 200 302 10m;    # 200/302 响应缓存 10 分钟
        proxy_cache_valid 404 1m;          # 404 缓存 1 分钟
        proxy_cache_use_stale error timeout http_500;
        add_header X-Cache-Status $upstream_cache_status;  # 查看缓存命中状态
    }
}

# 限流:每个 IP 每秒最多 5 个请求
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=5r/s;

server {
    location /api/ {
        limit_req zone=mylimit burst=10 nodelay;
        proxy_pass http://backend;
    }
}

7. location 匹配规则详解

写法类型优先级示例 URI 命中情况
location = /exact精确匹配1(最高)只有 /exact 命中,/exact/ 不命中
location ^~ /img/前缀匹配(非正则)2/img/a.png 命中且不再检查正则
location ~ \.php$正则匹配(区分大小写)3/index.php 命中;按书写顺序取第一个匹配
location ~* \.(jpg|png)$正则匹配(不区分大小写)3/a.JPG/b.png 都命中
location /普通前缀匹配4(最低)兜底,取最长匹配前缀
# 一个完整的 location 路由示例
server {
    location = /favicon.ico {           # 精确匹配:缩短小文件访问路径
        log_not_found off;
        access_log off;
    }
    location ^~ /static/ {              # 静态资源:不再检查正则,直接走文件服务
        alias /var/www/static/;
        expires 7d;                     # 浏览器缓存 7 天
    }
    location ~ \.php$ {                 # PHP 动态请求转发到 FPM
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    }
    location / {                        # 其余全部走前端应用
        proxy_pass http://node_app;
    }
}

8. proxy_pass 的 URI 传递规则

proxy_pass 结尾是否带 /,决定了匹配到的 location 前缀是否被剥离,这是新手最容易搞错的点:

配置请求 /api/users/1 到达后端说明
location /api/ { proxy_pass http://backend; }/api/users/1不带 URI,原样转发(保留前缀)
location /api/ { proxy_pass http://backend/; }/users/1/,location 前缀被替换
location /api { proxy_pass http://backend; }/api/users/1不带 URI,原样转发
location /api/ { proxy_pass http://backend/v2/; }/v2/users/1前缀被 /v2/ 替换
# 常见实践:前端 SPA 与 API 分离
server {
    listen 80;
    server_name app.example.com;

    # 静态前端(Vue/React 构建产物)
    location / {
        root /var/www/app/dist;
        try_files $uri $uri/ /index.html;   # SPA 路由回退
    }

    # API 反向代理:剥离 /api 前缀
    location /api/ {
        proxy_pass http://127.0.0.1:8080/;  # 注意结尾斜杠
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

9. 负载均衡策略详解

# 策略一:轮询(默认)——请求依次分发,权重可配
upstream app1 {
    server 192.168.1.10:8080 weight=3;    # 权重 3:每 4 个请求分到 3 个
    server 192.168.1.11:8080 weight=1;
    server 192.168.1.12:8080 down;        # 手动标记下线(不参与分发)
}

# 策略二:ip_hash——同一客户端 IP 固定打到同一台后端(会话保持)
upstream app2 {
    ip_hash;
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
}

# 策略三:least_conn——分给当前活跃连接最少的后端
upstream app3 {
    least_conn;
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
}

# 策略四:fair(第三方模块)/ url_hash——按响应时间或 URL 分发,需编译安装

# 后端故障处理:fail_timeout 内失败 max_fails 次则标记不可用
upstream app4 {
    server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
    server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
    server 192.168.1.12:8080 backup;      # 仅当主后端全挂时启用
}

# 验证分发效果:循环请求观察后端日志
for i in $(seq 1 8); do curl -s http://localhost/ > /dev/null; done

10. 缓存完整配置与动静分离

# http 块:定义缓存目录与共享区
proxy_cache_path /var/cache/nginx levels=1:2
                 keys_zone=api_cache:10m
                 max_size=5g
                 inactive=60m
                 use_temp_path=off;

# 动静分离:静态文件直接返回,动态请求才进缓存
server {
    listen 80;
    server_name www.example.com;

    # 静态资源:交给 Nginx 文件服务,不经过代理
    location ~* \.(css|js|png|jpg|jpeg|gif|ico|woff2?)$ {
        root /var/www/site;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    # 动态 API:进缓存
    location /api/ {
        proxy_pass http://backend;
        proxy_cache api_cache;              # 启用缓存区
        proxy_cache_key "$scheme$request_method$host$request_uri";
        proxy_cache_valid 200 302 10m;      # 成功响应缓存 10 分钟
        proxy_cache_valid 404 1m;           # 404 只缓存 1 分钟
        proxy_cache_use_stale error timeout http_500 http_502 http_503;
        add_header X-Cache-Status $upstream_cache_status;  # HIT/MISS/EXPIRED
    }
}

# 手动清理某条缓存(按 proxy_cache_key 生成路径删除)
find /var/cache/nginx -type f | grep -E "$(echo -n 'GEThttp://api.example.com/api/user' | md5sum | cut -d' ' -f1)" | xargs rm -f

11. 安全加固

# 隐藏版本号(默认响应头 Server: nginx/1.24.0 → Server: nginx)
server_tokens off;

# 隐藏 PHP 版本号等上游信息(适用于 FastCGI 场景)
fastcgi_hide_header X-Powered-By;

# 限制请求方法,拒绝非法的 TRACE/OPTIONS
if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE)$) {
    return 405;
}

# 完整限流:登录接口每 IP 每分钟 5 次,防暴力破解
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=5r/m;

server {
    location /login {
        limit_req zone=login_limit burst=3 nodelay;
        limit_req_status 429;              # 超过则返回 429 Too Many Requests
        proxy_pass http://backend;
    }
}

# 限制并发连接数:每 IP 最多 10 个连接
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
server {
    limit_conn conn_limit 10;
}

# 基础 WAF 头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

# 禁止访问隐藏文件与备份文件
location ~ /\. { deny all; }
location ~ \.(sql|bak|tar|zip|log)$ { deny all; }

常见错误

错误表现根因正确做法
nginx: [emerg] "server" directive is not allowed hereserver 块写在了 http 块之外所有 server 块必须放在 http { } 内部
访问域名时显示默认页而不是配置的站点server_nameroot 路径配置错误检查 server_name 是否匹配域名,root 路径是否存在并有正确权限
修改配置后不生效只修改了文件但没有 reload 或重启nginx -t 检查语法,然后 systemctl reload nginx
502 Bad GatewayNginx 无法连接到 proxy_pass 配置的后端检查后端进程是否运行、端口是否正确、防火墙是否放行
413 Request Entity Too Large上传文件大小超过 Nginx 默认限制(1MB)http/server/location 块中增加 client_max_body_size 50m;
504 Gateway Timeout后端处理时间超过 proxy_read_timeout(默认 60 秒)按业务调整 proxy_read_timeout 300,同时排查后端慢查询/长任务
429 Too Many Requests命中 limit_req 限流调整 rateburst;检查是否有爬虫或客户端未按频率控制
代理后端的静态资源 404proxy_pass 结尾 / 导致前缀被剥离,后端找不到路径核对"8. proxy_pass 的 URI 传递规则"表格,确认前缀是否该保留
worker_connections are not enough并发连接超过 worker_processes × worker_connections排查连接泄漏;确认 keepalive 配置;必要时调大 worker_connections
修改配置后 nginx -t 通过但站点仍报错修改的文件不是实际加载的配置文件(如改了 conf.d 但 include 的是 sites-enablednginx -T 输出实际生效的完整配置,核对加载路径

最佳实践

实践原理示例
配置修改前备份防误操作导致服务不可用cp /etc/nginx/nginx.conf{,.bak} 或使用 Git 管理配置
每次修改后用 nginx -t 验证语法错误会导致 Nginx 启动失败alias: sudo nginx -t && sudo systemctl reload nginx
worker 进程数设为 CPU 核心数最佳 CPU 利用率worker_processes auto;
开启 SSL session cache减少 TLS 握手开销ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m;
定期检查访问日志发现异常流量和攻击sudo tail -f /var/log/nginx/access.log | cut -d' ' -f1 | sort | uniq -c | sort -rn
为敏感路径加访问控制最小暴露原则location ~ /\. { deny all; } 禁止访问隐藏文件
开启 access log 与错误日志分级故障排查的第一手依据error_log /var/log/nginx/error.log warn; 生产避免 debug 级别
静态资源与动态请求分离静态文件不占后端连接,吞吐更高css/js/图片走 expires 30d 文件服务,动态走 proxy_pass
限流与连接数限制按业务拆分 zone避免单个接口的突发流量拖垮整个站点登录接口独立 limit_req_zone,与普通 API 互不影响

练习题

  1. (概念)Nginx 的事件驱动架构和 Apache 的进程每连接模型有什么本质区别?为什么 Nginx 在高并发场景下更省资源?
  2. (概念)location 指令中 = /exact^~ /prefix~ regex 三种写法的优先级顺序是什么?
  3. (实操)在本地 Nginx 上配置两个虚拟主机:site1.localsite2.local,分别指向 /var/www/site1/var/www/site2,在两个目录下各放一个不同的 index.html。修改 /etc/hosts 添加解析,用浏览器验证是否能正确访问两个站点。
  4. (实操)配置一个反向代理,将 /app/ 路径的请求转发到 http://localhost:3000,同时设置正确的代理头(HostX-Real-IPX-Forwarded-For)。用 curl 或浏览器测试代理是否正常工作。
  5. (🔍 挑战)使用 certbot 在测试环境中获取 Let's Encrypt 证书并配置完整的 HTTPS 站点(包括 HTTP→HTTPS 跳转、HSTS、SSL 协议限制)。如果无法获取真实证书,也可以创建自签名证书模拟配置。完成后用 SSLLabs SSL Server Test(ssllabs.com)或 openssl s_client 验证安全配置。
点击查看答案
  1. (概念)Nginx 使用事件驱动 + 异步非阻塞 I/O(单进程处理数千连接),Apache 使用进程/线程每连接模型(每个连接消耗独立进程/线程)。Nginx 在并发高时内存和 CPU 开销远低于 Apache,因为不产生大量进程上下文切换。
  2. (概念)优先级从高到低:= /exact(精确匹配最高)→ ^~ /prefix(前缀匹配,匹配后不再检查正则)→ ~ regex(正则匹配,按在配置中出现顺序)→ 普通前缀匹配(最长匹配胜出)。
  3. (实操)/etc/nginx/sites-available/ 下为每个站点创建 server block,server_name site1.local + root /var/www/site1。然后 ln -ssites-enabled。最终 /etc/hosts 添加 127.0.0.1 site1.local site2.local。验证:curl http://site1.localcurl http://site2.local 返回不同内容。
  4. (实操)location 配置:location /app/ { proxy_pass http://localhost:3000; 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_pass 结尾是否带 / 会影响路径拼接方式——带 / 会截断匹配到的 /app 前缀。
  5. (🔍 挑战)Certbot 命令:sudo certbot --nginx -d example.com。HTTPS 配置关键参数:ssl_protocols TLSv1.2 TLSv1.3;ssl_prefer_server_ciphers on;。HSTS:add_header Strict-Transport-Security "max-age=63072000" always;。验证工具:openssl s_client -connect localhost:443 可查看证书链和 TLS 版本。

学习检查点

学完本章后,请检验自己是否掌握以下内容:

检查项自测问题验证方法
概念理解能用自己的话解释 Nginx 事件驱动架构与 Apache 进程模型的区别尝试向他人讲解
命令操作能不查文档完成 Nginx 虚拟主机配置、反向代理设置、HTTPS 证书申请在终端实际执行
原理掌握能说出 Nginx location 匹配优先级和反向代理工作原理画出流程图
故障排查能独立排查 Nginx 配置错误、502/504 网关错误、HTTPS 证书问题模拟故障并修复
最佳实践能说明为什么需要配置 gzip 压缩和缓存策略对比不同方案

本章总结

Nginx 是当今互联网基础设施的基石。它以事件驱动、异步非阻塞的架构实现了高并发低占用的目标,同时提供了虚拟主机、反向代理、负载均衡、HTTPS 终结、缓存限流等丰富的功能。掌握 server block、location 匹配、proxy_pass 三大核心概念,配合 nginx -t 测试和 reload 热重载,就能在生产环境中游刃有余地管理 Nginx。

速查表

命令/指令用途
sudo nginx -t测试配置语法
sudo systemctl reload nginx热重载配置(不中断连接)
server_name指定虚拟主机匹配的域名
location /path { }按 URI 路径匹配并执行规则
proxy_pass http://backend反向代理到后端
upstream name { }定义后端服务器池(负载均衡)
return 301 https://$host$uriHTTP 到 HTTPS 的 301 跳转
client_max_body_size 50m设置上传文件大小上限
gzip on启用响应压缩
limit_req_zone + limit_req请求限流
proxy_cache_path + proxy_cache配置反向代理缓存

学习路径建议

延伸阅读

常见问题

Nginx location 匹配顺序规则?
优先级从高到低:= 精确匹配 > ^~ 前缀匹配(若匹配则停止)> ~ 正则匹配(按出现顺序)> 普通前缀匹配。记住:精确匹配最高优先级,正则匹配按文件中的先后顺序,普通前缀匹配取最长匹配。在复杂站点中建议用 ^~ 显式控制匹配优先级。
反向代理后端返回 502 怎么排查?
502 Bad Gateway 通常是后端服务没启动或端口不对。依次检查:① systemctl status 后端服务是否 running;② ss -tlnp 确认监听端口;③ 防火墙是否放行;④ Nginx 配置中 proxy_pass URL 末尾的 / 是否和 location 正确搭配。最简单测试:curl http://127.0.0.1:后端端口 直接访问后端。
Nginx 做负载均衡 upstream 怎么配置健康检查?
Nginx 开源版没有主动健康检查,通过被动方式实现:server 指令中的 max_fails(允许失败次数)和 fail_timeout(失败后暂停时间)。Nginx Plus 有主动 health_check。可以考虑用 HAProxy 做负载均衡(自带主动健康检查),Nginx 专注反向代理和缓存。
↑ 回到顶部