Skip to content

Nginx 配置面试题集

Nginx 核心配置与高频面试题

A. 面试宝典

基础题

1. Nginx 概述

┌─────────────────────────────────────────────────────────────┐
│                    Nginx 特点与应用                          │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  核心特点:                                                  │
│  ├── 高性能:异步非阻塞,单机支持数万并发                   │
│  ├── 低内存:内存占用少                                     │
│  ├── 高可靠:热部署、平滑重启                               │
│  ├── 模块化:功能模块化设计                                 │
│  └── 跨平台:支持 Linux、Windows、macOS                     │
│                                                              │
│  主要应用:                                                  │
│  ├── Web 服务器:静态资源服务                               │
│  ├── 反向代理:代理后端服务                                 │
│  ├── 负载均衡:分发请求到多台服务器                         │
│  ├── HTTP 缓存:缓存后端响应                                │
│  └── API 网关:路由、限流、认证                             │
│                                                              │
│  工作模型:                                                  │
│  ├── Master 进程:管理 Worker 进程                          │
│  └── Worker 进程:处理请求(通常等于 CPU 核心数)           │
│                                                              │
└─────────────────────────────────────────────────────────────┘

常用命令:

bash
# 启动
nginx                       # 启动
nginx -c /path/nginx.conf   # 指定配置文件启动

# 停止
nginx -s stop               # 快速停止
nginx -s quit               # 优雅停止(等待请求处理完)

# 重载配置
nginx -s reload             # 重载配置(不停机)
nginx -s reopen             # 重新打开日志文件

# 检查配置
nginx -t                    # 测试配置语法
nginx -T                    # 测试并输出配置

# 查看版本
nginx -v                    # 版本
nginx -V                    # 版本和编译参数

2. 配置文件结构

nginx
# nginx.conf 基本结构
# ============================================

# 全局块
user nginx;                         # 运行用户
worker_processes auto;              # Worker 进程数(auto = CPU核心数)
error_log /var/log/nginx/error.log; # 错误日志
pid /run/nginx.pid;                 # PID 文件

# 事件块
events {
    worker_connections 1024;        # 每个 Worker 最大连接数
    use epoll;                      # 事件模型(Linux 用 epoll)
    multi_accept on;                # 一次接受多个连接
}

# HTTP 块
http {
    # 基础设置
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    # 日志格式
    log_format main '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent"';

    access_log /var/log/nginx/access.log main;

    # 性能优化
    sendfile on;                    # 零拷贝
    tcp_nopush on;                  # 优化数据包发送
    tcp_nodelay on;                 # 禁用 Nagle 算法
    keepalive_timeout 65;           # 保持连接超时

    # Gzip 压缩
    gzip on;
    gzip_types text/plain text/css application/json application/javascript;

    # 包含其他配置
    include /etc/nginx/conf.d/*.conf;

    # Server 块
    server {
        listen 80;
        server_name example.com;
        root /var/www/html;

        # Location 块
        location / {
            index index.html;
        }
    }
}

3. 静态资源服务

nginx
server {
    listen 80;
    server_name static.example.com;

    # 静态文件根目录
    root /var/www/static;

    # 默认首页
    index index.html index.htm;

    # 静态资源缓存
    location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 30d;                        # 缓存30天
        add_header Cache-Control "public";
    }

    # 禁止访问隐藏文件
    location ~ /\. {
        deny all;
    }

    # 防盗链
    location ~* \.(jpg|jpeg|png|gif)$ {
        valid_referers none blocked server_names *.example.com;
        if ($invalid_referer) {
            return 403;
        }
    }

    # 目录列表(调试用)
    location /files/ {
        autoindex on;                       # 开启目录浏览
        autoindex_exact_size off;           # 显示文件大小
        autoindex_localtime on;             # 显示本地时间
    }

    # try_files 尝试查找文件
    location / {
        try_files $uri $uri/ /index.html;   # SPA 路由支持
    }

    # 错误页面
    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;

    location = /50x.html {
        root /usr/share/nginx/html;
    }
}

4. 反向代理

nginx
# 基础反向代理
# ============================================

upstream backend {
    server 127.0.0.1:3000;
}

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

    location / {
        proxy_pass http://backend;

        # 代理头设置
        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 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;

        # 缓冲设置
        proxy_buffering on;
        proxy_buffer_size 4k;
        proxy_buffers 8 4k;
    }

    # WebSocket 代理
    location /ws {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_read_timeout 3600s;           # WebSocket 长连接
    }
}

# 多路径代理
server {
    listen 80;
    server_name example.com;

    # API 服务
    location /api/ {
        proxy_pass http://127.0.0.1:3000/;
    }

    # 用户服务
    location /user/ {
        proxy_pass http://127.0.0.1:3001/;
    }

    # 静态资源
    location / {
        root /var/www/frontend;
        try_files $uri $uri/ /index.html;
    }
}

5. 负载均衡

nginx
# 负载均衡策略
# ============================================

# 1. 轮询(默认)
upstream backend {
    server 192.168.1.1:8080;
    server 192.168.1.2:8080;
    server 192.168.1.3:8080;
}

# 2. 加权轮询
upstream backend {
    server 192.168.1.1:8080 weight=5;       # 权重5
    server 192.168.1.2:8080 weight=3;       # 权重3
    server 192.168.1.3:8080 weight=2;       # 权重2
}

# 3. IP Hash(会话保持)
upstream backend {
    ip_hash;
    server 192.168.1.1:8080;
    server 192.168.1.2:8080;
    server 192.168.1.3:8080;
}

# 4. 最少连接
upstream backend {
    least_conn;
    server 192.168.1.1:8080;
    server 192.168.1.2:8080;
    server 192.168.1.3:8080;
}

# 5. URL Hash(需要第三方模块)
upstream backend {
    hash $request_uri consistent;
    server 192.168.1.1:8080;
    server 192.168.1.2:8080;
}

# 服务器状态参数
upstream backend {
    server 192.168.1.1:8080 weight=5;
    server 192.168.1.2:8080 backup;         # 备用服务器
    server 192.168.1.3:8080 down;           # 下线
    server 192.168.1.4:8080 max_fails=3 fail_timeout=30s;
}

# 健康检查(商业版或第三方模块)
upstream backend {
    server 192.168.1.1:8080;
    server 192.168.1.2:8080;

    # 需要 nginx_upstream_check_module
    check interval=3000 rise=2 fall=3 timeout=1000 type=http;
    check_http_send "HEAD /health HTTP/1.0\r\n\r\n";
    check_http_expect_alive http_2xx http_3xx;
}

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://backend;
        proxy_next_upstream error timeout http_500 http_502 http_503;
    }
}

进阶题

6. HTTPS 配置

nginx
server {
    listen 443 ssl http2;
    server_name example.com;

    # SSL 证书
    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;

    # SSL 协议版本
    ssl_protocols TLSv1.2 TLSv1.3;

    # 加密套件
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers on;

    # SSL 会话缓存
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;

    # HSTS
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    location / {
        root /var/www/html;
        index index.html;
    }
}

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

7. 缓存配置

nginx
# 代理缓存
# ============================================

http {
    # 定义缓存路径
    proxy_cache_path /var/cache/nginx
                     levels=1:2
                     keys_zone=my_cache:10m
                     max_size=10g
                     inactive=60m
                     use_temp_path=off;

    server {
        listen 80;
        server_name example.com;

        location / {
            proxy_pass http://backend;

            # 启用缓存
            proxy_cache my_cache;
            proxy_cache_key $scheme$request_method$host$request_uri;

            # 缓存有效期
            proxy_cache_valid 200 302 10m;
            proxy_cache_valid 404 1m;

            # 缓存条件
            proxy_cache_bypass $http_cache_control;
            proxy_no_cache $http_pragma;

            # 添加缓存状态头
            add_header X-Cache-Status $upstream_cache_status;

            # 过期后允许使用过期缓存
            proxy_cache_use_stale error timeout updating http_500 http_502;

            # 后台更新缓存
            proxy_cache_background_update on;
        }

        # 不缓存的路径
        location ~ ^/(api|admin) {
            proxy_pass http://backend;
            proxy_cache off;
        }
    }
}

# 静态资源缓存
server {
    listen 80;
    server_name static.example.com;

    location ~* \.(css|js)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    location ~* \.(jpg|jpeg|png|gif|ico|webp)$ {
        expires 30d;
        add_header Cache-Control "public";
    }

    location ~* \.(html|htm)$ {
        expires -1;
        add_header Cache-Control "no-store, no-cache, must-revalidate";
    }
}

8. 限流配置

nginx
http {
    # 定义限流区域
    # 按 IP 限制请求速率
    limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;

    # 按 IP 限制连接数
    limit_conn_zone $binary_remote_addr zone=conn_limit:10m;

    server {
        listen 80;
        server_name example.com;

        # 请求速率限制
        location /api/ {
            limit_req zone=req_limit burst=20 nodelay;
            # burst: 突发请求数
            # nodelay: 不延迟处理突发请求

            proxy_pass http://backend;
        }

        # 连接数限制
        location /download/ {
            limit_conn conn_limit 5;         # 每 IP 最多5个连接
            limit_rate 500k;                 # 限速 500KB/s

            root /var/www/files;
        }

        # 自定义限流响应
        limit_req_status 429;
        limit_conn_status 429;

        error_page 429 /429.html;
        location = /429.html {
            root /var/www/error;
        }
    }
}

# 基于地理位置限流
http {
    geo $limit {
        default 1;
        10.0.0.0/8 0;                       # 内网不限制
        192.168.0.0/16 0;
    }

    map $limit $limit_key {
        0 "";
        1 $binary_remote_addr;
    }

    limit_req_zone $limit_key zone=req_limit:10m rate=5r/s;
}

9. 日志配置

nginx
http {
    # 自定义日志格式
    log_format main '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" '
                    '"$http_x_forwarded_for" '
                    '$request_time $upstream_response_time';

    log_format json escape=json
        '{"time":"$time_iso8601",'
        '"remote_addr":"$remote_addr",'
        '"request":"$request",'
        '"status":$status,'
        '"body_bytes_sent":$body_bytes_sent,'
        '"request_time":$request_time,'
        '"upstream_response_time":"$upstream_response_time",'
        '"http_referer":"$http_referer",'
        '"http_user_agent":"$http_user_agent"}';

    # 默认访问日志
    access_log /var/log/nginx/access.log main;

    # 按域名分离日志
    server {
        server_name example.com;
        access_log /var/log/nginx/example.com.access.log main;
        error_log /var/log/nginx/example.com.error.log warn;
    }

    # 条件日志
    map $status $loggable {
        ~^[23] 0;                            # 2xx、3xx 不记录
        default 1;
    }

    server {
        access_log /var/log/nginx/error.access.log main if=$loggable;
    }

    # 关闭日志
    location /health {
        access_log off;
        return 200 "OK";
    }
}

# 日志常用变量
# $remote_addr        客户端 IP
# $remote_user        客户端用户名
# $time_local         本地时间
# $request            请求行
# $status             响应状态码
# $body_bytes_sent    发送的字节数
# $http_referer       来源页面
# $http_user_agent    用户代理
# $request_time       请求处理时间
# $upstream_response_time 上游响应时间

10. 安全配置

nginx
server {
    listen 80;
    server_name example.com;

    # 安全响应头
    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 Content-Security-Policy "default-src 'self'" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    # 隐藏版本号
    server_tokens off;

    # 禁止特定 User-Agent
    if ($http_user_agent ~* (wget|curl|libwww-perl)) {
        return 403;
    }

    # 禁止特定请求方法
    if ($request_method !~ ^(GET|POST|HEAD)$) {
        return 405;
    }

    # 防止目录遍历
    location ~ /\. {
        deny all;
    }

    # 限制上传大小
    client_max_body_size 10m;

    # 基础认证
    location /admin {
        auth_basic "Admin Area";
        auth_basic_user_file /etc/nginx/.htpasswd;

        proxy_pass http://backend;
    }

    # IP 白名单
    location /internal {
        allow 192.168.1.0/24;
        allow 10.0.0.0/8;
        deny all;

        proxy_pass http://backend;
    }
}

# 防止 DDoS
http {
    # 限制连接
    limit_conn_zone $binary_remote_addr zone=addr:10m;
    limit_conn addr 100;

    # 限制请求速率
    limit_req_zone $binary_remote_addr zone=one:10m rate=30r/m;
    limit_req zone=one burst=5;
}

避坑指南

问题解决方案
proxy_pass 末尾有无 // 会替换 location,无 / 会追加
502 Bad Gateway检查后端服务是否启动、端口是否正确
504 Gateway Timeout增加 proxy_read_timeout
配置不生效执行 nginx -t && nginx -s reload
权限问题检查 user 配置和文件权限

B. 实战文档

完整配置模板

nginx
# /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections 4096;
    use epoll;
    multi_accept on;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for" '
                    '$request_time $upstream_response_time';

    access_log /var/log/nginx/access.log main;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;

    # Gzip
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types text/plain text/css text/xml application/json application/javascript
               application/xml application/xml+rss text/javascript;

    # 安全
    server_tokens off;

    # 缓存
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=cache:10m
                     max_size=1g inactive=60m use_temp_path=off;

    # 限流
    limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
    limit_conn_zone $binary_remote_addr zone=conn:10m;

    # 上游服务
    upstream backend {
        least_conn;
        server 127.0.0.1:3000 weight=5;
        server 127.0.0.1:3001 weight=3;
        keepalive 32;
    }

    include /etc/nginx/conf.d/*.conf;
}

前后端分离配置

nginx
# /etc/nginx/conf.d/app.conf
server {
    listen 80;
    server_name example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com;

    # SSL
    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;
    ssl_protocols TLSv1.2 TLSv1.3;

    # 安全头
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;

    # 前端静态资源
    root /var/www/frontend/dist;

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

    # 静态资源缓存
    location ~* \.(css|js)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    location ~* \.(jpg|jpeg|png|gif|ico|svg|webp)$ {
        expires 30d;
        add_header Cache-Control "public";
    }

    # API 代理
    location /api/ {
        limit_req zone=api burst=20 nodelay;

        proxy_pass http://backend/;
        proxy_http_version 1.1;
        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_set_header Connection "";

        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }

    # WebSocket
    location /ws/ {
        proxy_pass http://backend/ws/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_read_timeout 3600s;
    }

    # 健康检查
    location /health {
        access_log off;
        return 200 "OK";
    }
}

Location 匹配规则

┌─────────────────────────────────────────────────────────────┐
│                    Location 匹配优先级                       │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  优先级从高到低:                                            │
│                                                              │
│  1. =  精确匹配                                              │
│     location = /exact { }                                   │
│                                                              │
│  2. ^~ 前缀匹配(停止正则搜索)                              │
│     location ^~ /static/ { }                                │
│                                                              │
│  3. ~  区分大小写的正则                                      │
│     location ~ \.php$ { }                                   │
│                                                              │
│  4. ~* 不区分大小写的正则                                    │
│     location ~* \.(jpg|png)$ { }                            │
│                                                              │
│  5. /  普通前缀匹配                                          │
│     location / { }                                          │
│                                                              │
│  匹配流程:                                                  │
│  1. 先检查所有前缀匹配,记住最长匹配                         │
│  2. 如果最长匹配是 = 或 ^~,直接使用                         │
│  3. 否则按顺序检查正则,使用第一个匹配的                     │
│  4. 如果没有正则匹配,使用之前记住的最长前缀匹配             │
│                                                              │
└─────────────────────────────────────────────────────────────┘

常见变量

nginx
# 请求相关
$request            # 完整请求行
$request_method     # 请求方法
$request_uri        # 带参数的 URI
$uri                # 不带参数的 URI
$args               # 查询参数
$query_string       # 同 $args
$scheme             # 协议 http/https
$host               # 主机名
$server_name        # 服务器名

# 客户端
$remote_addr        # 客户端 IP
$remote_port        # 客户端端口
$http_user_agent    # User-Agent
$http_referer       # Referer
$http_cookie        # Cookie
$http_x_forwarded_for  # 代理链 IP

# 响应
$status             # 响应状态码
$body_bytes_sent    # 发送的字节数

# 时间
$time_local         # 本地时间
$time_iso8601       # ISO 8601 格式时间
$request_time       # 请求处理时间
$upstream_response_time # 上游响应时间

基于 VitePress 构建