面试官最想听的 Nginx 优化答案:直接上生产级配置!

引言

nginx的优化配置, 向优秀的人学习!

1. 如何优化 Nginx 的并发处理能力?

Nginx 在高并发环境下表现优异,主要得益于它的事件驱动架构。为了进一步优化并发处理能力,可以调整以下配置:

  • worker_processes:设置 worker_processes 为与系统 CPU 核心数相同的数量,以充分利用多核 CPU。

    worker_processes 4; # 根据服务器的 CPU 核心数进行调整
    
  • worker_connections:每个 worker 进程可以处理的最大连接数,增加此值可以提升并发能力。

    worker_connections 1024; # 每个工作进程最多处理 1024 个连接
    
  • events:启用 epoll(Linux)或 kqueue(Mac)等高效的事件驱动模型,以提升 I/O 处理效率。

    events {
        use epoll; # 适用于 Linux 系统
        worker_connections 1024;
    }
    

这些设置可以帮助 Nginx 更高效地处理并发连接,提升系统的整体吞吐量。

2. 如何通过缓存优化 Nginx 性能?

Nginx 具有强大的缓存功能,可以通过缓存机制大幅度减少后端服务器的负载,降低响应时间。

  • HTTP 缓存:可以通过配置 proxy_cache 来缓存响应,避免每次请求都转发到后端服务。

    http {
        proxy_cache_path /tmp/cache levels=1:2 keys_zone=my_cache:10m inactive=60m max_size=1g;
        server {
            listen 80;
            location / {
                proxy_cache my_cache;
                proxy_pass http://backend;
                proxy_cache_valid 200 1h; # 对于 200 状态码的响应,缓存 1 小时
                proxy_cache_use_stale error timeout updating; # 错误或超时情况下使用陈旧缓存
            }
        }
    }
    
  • 静态文件缓存:静态资源(如图片、CSS、JavaScript 等)适合缓存,可以通过设置缓存头来减少带宽消耗。

    server {
        location /images/ {
            expires 30d; # 设置缓存过期时间为 30 天
            add_header Cache-Control "public";
        }
    }
    

缓存不仅能提升 Nginx 的性能,还能降低后端服务的压力,尤其适用于静态内容。

3. 如何优化 Nginx 的响应时间和带宽利用率?

  • 开启 Gzip 压缩:Nginx 支持 Gzip 压缩,能够显著减小传输内容的大小,提高带宽利用率,并减少响应时间。

    http {
        gzip on;
        gzip_min_length 1024; # 启用 Gzip 压缩,且只对大于 1KB 的内容生效
        gzip_types text/plain text/css application/javascript application/json;
    }
    
  • TCP_NOPUSH 和 TCP_NODELAY:在高延迟环境下,可以通过启用 TCP 优化选项来提高性能,减少等待数据包的时间。

    server {
        listen 80;
        tcp_nopush on; # 优化网络传输
        tcp_nodelay on; # 降低延迟
    }
    
  • 优化传输协议:启用 HTTP/2 协议,它具有多路复用、头部压缩和请求优先级等特性,能显著提升网页加载速度。

    server {
        listen 443 ssl http2;
        server_name example.com;
        ssl_certificate /path/to/certificate.crt;
        ssl_certificate_key /path/to/certificate.key;
    }
    

4. 如何减少 Nginx 配置中的瓶颈?

Nginx 配置的瓶颈通常出现在以下几个方面:

  • Nginx 配置文件结构:确保配置文件的结构清晰,避免过多的 locationserver 块,从而减少 Nginx 解析配置的复杂度。
  • 避免过多的正则表达式:正则匹配会消耗较多的 CPU 资源,尽量避免在 location 块中使用复杂的正则表达式,或者将其替换为路径匹配。
  • 合并 server 和 location 配置:尽量避免重复配置相同的内容,合理利用 include 来复用通用配置,减少冗余。
  • 减小负载均衡策略的复杂性:负载均衡时,如果有多个后端服务器,尽量简化负载均衡算法,使用简单的轮询算法,避免复杂的健康检查和权重设置。

5. 如何配置 Nginx 的日志以减少 I/O 开销?

Nginx 的日志功能在生产环境中非常重要,但过多的日志写入会导致 I/O 开销,影响性能。

  • 禁用访问日志:在高流量情况下,如果不需要访问日志,可以通过设置 access_log off; 来禁用访问日志。

    server {
        listen 80;
        access_log off;
        location / {
            proxy_pass http://backend;
        }
    }
    
  • 日志缓冲:使用 log_format 指令定义自定义日志格式,并且利用 access_log 的缓冲机制来减少磁盘 I/O。可以设置 bufferflush 参数来控制日志的刷新频率。

    http {
        log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                        '$status $body_bytes_sent "$http_referer" '
                        '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log /var/log/nginx/access.log main buffer=32k flush=5m;
    }
    

6. 如何优化 Nginx 配置以防止 DDoS 攻击?

通过以下配置,Nginx 可以有效地防止恶意流量和 DDoS 攻击:

  • 限制请求速率:使用 limit_req 模块限制每个 IP 地址的请求速率。

    http {
        limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
        server {
            listen 80;
            location / {
                limit_req zone=req_limit burst=20 nodelay;
                proxy_pass http://backend;
            }
        }
    }
    
  • 限制每个客户端的最大连接数:通过 limit_conn 模块限制每个客户端的最大并发连接数。

    http {
        limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
        server {
            listen 80;
            location / {
                limit_conn conn_limit 1; # 每个客户端最多 1 个并发连接
                proxy_pass http://backend;
            }
        }
    }
    
  • 增加连接超时:设置适当的连接超时和读取超时,防止长时间未处理的连接占用过多资源。

    http {
        client_body_timeout 10s;
        client_header_timeout 10s;
        send_timeout 10s;
    }
    

7. 如何优化 Nginx 的 SSL/TLS 性能?

Nginx 在处理 HTTPS 时需要高效地配置 SSL/TLS,以减少加密解密的性能开销:

  • 启用 SSL/TLS 会话缓存:通过缓存 SSL/TLS 会话来减少握手时间。

    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1h;
    
  • 使用现代加密算法:配置安全的加密套件,并禁用过时的协议。

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'HIGH:!aNULL:!MD5';
    
  • 启用 OCSP Stapling:通过启用 OCSP Stapling 来提高 SSL/TLS 握手的速度。

    ssl_stapling on;
    ssl_stapling_verify on;
    

8. 如何排查 Nginx 性能瓶颈?

  • 监控 Nginx 状态:通过启用 Nginx 状态页面,实时监控 Nginx 的性能。

    server {
        listen 8080;
        location /status {
            stub_status on;
            access_log off;
            allow 127.0.0.1;
            deny all;
        }
    }
    
  • 日志分析:检查错误日志、访问日志,尤其关注高延迟或 5xx 错误,找出可能的性能瓶颈。

  • 系统资源监控:通过监控 CPU、内存、网络带宽和磁盘 I/O 等系统资源,定位 Nginx 服务器的瓶颈所在。

9. Nginx 如何实现高并发?

描述 master-worker 架构与 epoll 事件模型的协同工作原理:

  • Master 进程:负责读取配置、绑定端口、管理 Worker 进程(平滑重启、热加载)。
  • Worker 进程:实际处理请求,采用非阻塞 + epoll 多路复用机制。
  • Epoll 模型:基于事件驱动,仅遍历活跃连接,复杂度 O(1),支持百万级并发。
  • 配置优化项
    worker_processes auto; # 匹配 CPU 核心数
    worker_connections 10240; # 单个 Worker 最大连接数
    use epoll; # 明确指定事件模型
    

10. 以下配置存在什么问题?如何优化?

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

解析与优化

  • 问题:未传递客户端真实 IP,丢失关键信息。
  • 修复方案
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_http_version 1.1; # 启用长连接
    proxy_set_header Connection "";
    

11. 如何通过 Slab 分配器优化 Nginx 内存碎片?

内存分配公式

总内存需求 = worker_processes × (worker_connections × 请求缓冲区 + 响应缓冲区)

优化配置

slab_size 1m;
slab_page_size 4k;

client_body_buffer_size 16k;
client_header_buffer_size 4k;
large_client_header_buffers 8 32k;

connection_pool_size 4096;
request_pool_size 4k;

监控指标

nginx -V 2>&1 | grep -o 'with-debug' && kill -USR1 $(cat /run/nginx.pid)
tail -f /var/log/nginx/error.log | grep slab

12. 如何设计 Nginx 缓存策略防止高并发下的缓存穿透?

proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=mycache:1024m inactive=7d use_temp_path=off;

location / {
    proxy_cache mycache;
    proxy_cache_lock on; # 防击穿:同一请求仅一个回源
    proxy_cache_key "$scheme$request_method$host$request_uri";
    proxy_cache_valid 200 302 10m;
    proxy_cache_use_stale error timeout updating;
    proxy_cache_background_update on; # 后台更新缓存
}

13. 如何利用 Nginx + Lua 实现动态限频?

完整代码逻辑

lua_shared_dict limit_counter 10m;
server {
    location / {
        access_by_lua_block {
            local limit_counter = ngx.shared.limit_counter
            local key = ngx.var.binary_remote_addr
            local req, _ = limit_counter:get(key)

            if req then
                if req > 100 then # 每秒 100 次阈值
                    ngx.exit(503)
                else
                    limit_counter:incr(key, 1)
                end
            else
                limit_counter:set(key, 1, 1) # 过期时间 1 秒
            end
        }
    }
}

14. 如何通过 Nginx 拦截 SQL 注入和 XSS 攻击?

正则表达式和配置片段

set $block 0;
if ($request_method !~ ^(GET|POST)$ ) { set $block 1; }

if ($query_string ~* "union.*select.*from") { set $block 1; } # SQL 注入检测
if ($args ~* "<script.*>") { set $block 1; } # XSS 检测

location / {
    if ($block = 1) {
        return 444; # 静默丢弃攻击请求
    }
    # 其他业务逻辑
}

15. 如何构建 Nginx 全维度监控指标?

Prometheus + Grafana 方案

  • nginx.conf 开启 Stub Status

    location /nginx_status {
        stub_status;
        allow 127.0.0.1;
        deny all;
    }
    
  • Prometheus 配置

    job_name: 'nginx'
    static_configs:
    
  • Grafana 看板:包含 QPS、连接数、4xx/5xx 错误率、Upstream 响应时间分布。

16. 如何实现 Nginx 的零停机热升级?

完整操作流程及回滚方案

  1. 备份旧版本二进制文件:

    cp /usr/sbin/nginx /usr/sbin/nginx.old
    
  2. 编译新版本(需保留原 configure 参数):

    ./configure --with-http_v2_module --with-stream=dynamic...
    make && make install
    
  3. 向主进程发送 USR2 信号启动新进程:

    kill -USR2 $(cat /run/nginx.pid)
    
  4. 逐步关闭旧 Worker 进程:

    kill -WINCH $(cat /run/nginx.pid.oldbin)
    
  5. 强制回滚(若新版本异常):

    mv /usr/sbin/nginx.old /usr/sbin/nginx
    kill -HUP $(cat /run/nginx.pid.oldbin)
    

17. 如何基于 Nginx + GeoIP 实现跨国流量调度?

DNS 与 Nginx 联动方案

geoip_country /usr/share/GeoIP/GeoIP.dat;
map $geoip_country_code $backend {
    default us.web.service; # 默认美国集群
    CN cn.web.service; # 中国用户
    JP jp.web.service; # 日本用户
}

server {
    location / {
        resolver 8.8.8.8 valid=30s; # 动态 DNS 解析
        proxy_pass http://$backend;
        proxy_next_upstream error timeout http_500;
    }
}

18. 在 Kubernetes + Serverless 架构中,Nginx Ingress 如何实现自动弹性伸缩?

  • 水平扩展:基于 HPA 监控 CPU/内存自动扩缩 Pod 数量。
  • 智能路由:通过 Nginx Ingress Annotation 实现金丝雀发布:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "20"
    
  • 冷启动优化:预加载 Nginx 配置到内存池,减少首次请求延迟。

19. 如何将 HTTP/1.1 升级为 HTTP/2 并优化性能?

关键配置项

http {
    # 开启 HTTP/2
    listen 443 ssl http2;

    # 优化连接复用
    keepalive_timeout 300s;
    keepalive_requests 10000;

    # 头部压缩优化
    gzip on;
    gzip_min_length 1k;
    gzip_comp_level 3;
    gzip_types text/plain application/json;

    # 调整缓冲区应对大 Header
    http2_max_field_size 16k;
    http2_max_header_size 64k;

    # 动态调整窗口大小
    http2_body_preread_size 128k;
    http2_streams_index_size 1024;
}

性能指标

  • 连接复用率提升 40%+
  • 首字节时间(TTFB)降低 30%
  • 头部传输体积减少 50%

20. 设计防御大规模 CC 攻击的分布式限流方案,需支持动态规则更新

  • 分布式限流(Redis 集群)

    limit_req_zone $binary_remote_addr zone=global_limit:10m rate=100r/s;
    limit_req zone=global_limit burst=200 delay=10;
    
  • 动态规则 API

    location /api/limit_rules {
        # 接受 JSON 格式规则更新
        proxy_pass http://rule_engine;
    
        # 实时加载新规则
        nginx -s reload && lua_shared_dict limit_rules 10m;
    }
    
  • Lua 动态过滤

    access_by_lua_block {
        local rules = ngx.shared.limit_rules
        local ip = ngx.var.remote_addr
        if rules:get(ip) == "block" then
            ngx.exit(444)
        end
    }
    
  • 防御指标

    • 单 IP QPS 限制精度 ±5%
    • 规则更新延迟 < 500ms
    • 10Gbps 攻击流量过滤率 99.9%

21. 在 Kubernetes 中如何优化 Nginx Ingress Controller 性能?

  • 水平自动扩缩

    autoscaling:
      enabled: true
      minReplicas: 3
      maxReplicas: 100
      metrics:
        - type: Pods
          pods:
            metric:
              name: nginx_connections_active
            target:
              type: AverageValue
              averageValue: 1000
    
  • 内核参数调优(DaemonSet)

    sysctls:
      - name: net.core.somaxconn
        value: "65535"
      - name: net
    

参考视频链接:

https://mp.weixin.qq.com/s/ZAaJFxaEYlcWc4fwDmAdhw