高流量网站 Nginx 性能调优必备清单

利用这份必备的 Nginx 调优清单,释放您高流量网站的巅峰性能。这份综合指南涵盖了优化工作进程、管理连接、精细调整缓冲区以及实施强大缓存等关键配置。了解如何利用 Gzip 压缩、简化日志记录、调整超时设置以及保护 SSL/TLS,以实现更快的加载时间并降低服务器负载。提升您的 Nginx 配置,使其在繁忙的服务器上提供卓越的速度和可靠性。

55 浏览量

高流量网站Nginx性能调优必备清单

对于任何经历大量流量的网站来说,Nginx都是一个功能强大、高效的Web服务器和反向代理。然而,仅仅部署Nginx不足以保证在重负载下的最佳性能。正确的配置和调优对于充分发挥其潜力至关重要,能确保您的Web应用程序保持快速、响应灵敏且可靠。

本文提供了一份详尽的Nginx关键配置和指令清单,专门设计用于优化高流量环境下的性能。我们将涵盖从管理工作进程和连接到微调缓冲区、实施强大的缓存策略以及优化压缩的方方面面。通过系统地解决这些领域,您可以显著降低服务器负载,提高内容交付速度,并改善整体用户体验。

1. 优化工作进程和连接

Nginx采用主-工作进程模型。主进程读取配置并管理工作进程,而工作进程则处理实际的客户端请求。正确配置这些可以显著提高并发性和资源利用率。

worker_processes

此指令决定Nginx将生成多少个工作进程。通常,将其设置为auto允许Nginx检测CPU核心数量并生成相同数量的工作进程,这是一种常见的最佳实践。

worker_connections

定义单个工作进程可以打开的最大并发连接数。此设置与worker_processes结合使用,决定了Nginx可以处理的理论总并发连接数(worker_processes * worker_connections)。

multi_accept

使工作进程能够一次性接受多个新连接,在高负载下防止潜在的瓶颈。

# /etc/nginx/nginx.conf

worker_processes auto; # 通常设置为'auto'或CPU核心数

events {
    worker_connections 1024; # 根据服务器容量和预期负载进行调整
    multi_accept on;
}

提示: 监控服务器的CPU使用率。如果worker_processes设置为auto且CPU利用率持续很高,您可能需要考虑增加worker_connections或扩展服务器资源。

2. 高效连接管理

优化Nginx处理网络连接的方式可以减少开销并提高响应速度。

keepalive_timeout

指定keep-alive客户端连接保持打开的时间。复用连接可以减少建立新TCP连接和SSL握手的开销。常见的值是15-65秒,具体取决于您的应用程序的交互性。

sendfile

启用文件描述符之间的数据直接传输,绕过用户空间缓冲。这在提供静态文件时显著提高了性能。

tcp_nopush

sendfile配合使用。Nginx尝试在一个数据包中发送HTTP头和文件的开头。之后,它以完整的数据包发送数据。这减少了发送的数据包数量。

tcp_nodelay

指示Nginx在数据可用时立即发送,不进行缓冲。这对于低延迟比最大化吞吐量更关键的交互式应用程序(例如,聊天应用程序或实时更新)很有益。

http {
    keepalive_timeout 65; # keep-alive连接保持65秒
    sendfile on;
    tcp_nopush on; # 需要sendfile开启
    tcp_nodelay on; # 有助于代理动态内容
}

3. 缓冲区优化

Nginx使用缓冲区来处理客户端请求和来自上游服务器(如应用服务器)的响应。正确调整这些缓冲区的大小可以防止不必要的磁盘I/O,减少内存使用,并提高吞吐量。

客户端缓冲区

  • client_body_buffer_size: 客户端请求体的缓冲区大小。如果请求体超过此大小,它将被写入临时文件。
  • client_header_buffer_size: 客户端请求的第一行和请求头的缓冲区大小。
  • large_client_header_buffers: 定义用于读取客户端请求头的大型缓冲区的数量和大小。适用于包含许多cookie或长referer头的请求。

代理缓冲区 (用于反向代理设置)

  • proxy_buffers: 用于从代理服务器读取响应的缓冲区的数量和大小。
  • proxy_buffer_size: 用于读取响应的第一个缓冲区的大小。通常较小,因为它通常只包含头部信息。
  • proxy_busy_buffers_size: 处于“忙碌”状态(积极发送给客户端)的响应缓冲区的最大量。

FastCGI 缓冲区 (用于PHP-FPM等)

  • fastcgi_buffers: 用于从FastCGI服务器读取响应的缓冲区的数量和大小。
  • fastcgi_buffer_size: 用于读取响应的第一个缓冲区的大小。
http {
    # 客户端缓冲区
    client_body_buffer_size 1M; # 根据预期的请求体大小(例如文件上传)进行调整
    client_header_buffer_size 1k;
    large_client_header_buffers 4 8k; # 4个缓冲区,每个8KB

    # 代理缓冲区(如果Nginx充当反向代理)
    proxy_buffers 8 16k; # 8个缓冲区,每个16KB
    proxy_buffer_size 16k; # 第一个缓冲区16KB
    proxy_busy_buffers_size 16k; # 忙碌缓冲区最大16KB

    # FastCGI缓冲区(如果Nginx与PHP-FPM协同工作)
    fastcgi_buffers 116 8k; # 116个缓冲区,每个8KB(例如针对WordPress)
    fastcgi_buffer_size 16k; # 第一个缓冲区16KB
}

警告: 将缓冲区设置得太小可能导致磁盘I/O和性能下降。设置得太大则可能消耗过多内存。通过测试找到平衡点。

4. 实施强大的缓存策略

缓存是提高性能和减少后端服务器负载最有效的方法之一。Nginx可以作为强大的内容缓存。

proxy_cache_path

定义缓存目录的路径、大小、子目录级别数以及非活动项在缓存中保留的时间。

proxy_cache

为给定的location块激活缓存,引用proxy_cache_path中定义的区域。

proxy_cache_valid

设置Nginx缓存具有特定HTTP状态码的响应的时间。

proxy_cache_revalidate

启用时,Nginx将使用If-Modified-SinceIf-None-Match头与后端重新验证缓存内容,从而减少带宽使用。

proxy_cache_use_stale

指示Nginx在后端服务器宕机、无响应或出现错误时提供陈旧的缓存内容。这大大提高了可用性。

expires

为静态文件的客户端缓存设置Cache-ControlExpires头。这最大程度地减少了对Nginx的重复请求。

http {
    # 在http块中定义一个代理缓存区域
    proxy_cache_path /var/cache/nginx/my_cache levels=1:2 keys_zone=my_cache:10m inactive=60m max_size=10g;

    server {
        listen 80;
        server_name example.com;

        location / {
            proxy_pass http://my_upstream_backend;
            proxy_cache my_cache; # 为此位置启用缓存
            proxy_cache_valid 200 302 10m; # 缓存成功的响应10分钟
            proxy_cache_valid 404 1m; # 缓存404响应1分钟
            proxy_cache_revalidate on;
            proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
            add_header X-Cache-Status $upstream_cache_status; # 有助于调试
        }

        # 在浏览器中缓存静态文件更长时间
        location ~* \.(jpg|jpeg|gif|png|css|js|ico|woff|woff2|ttf|svg|eot)$ {
            expires 30d; # 缓存30天
            add_header Cache-Control "public, no-transform";
            # 对于静态文件,如果未代理,请考虑直接从Nginx提供服务
            root /var/www/html;
        }
    }
}

5. 启用Gzip压缩

在将响应发送给客户端之前进行压缩可以显著减少带宽使用并提高页面加载时间,特别是对于基于文本的内容。

gzip on

激活gzip压缩。

gzip_comp_level

设置压缩级别(1-9)。级别1最快但压缩率较低;级别9最慢但压缩率最高。级别6通常提供良好的平衡。

gzip_types

指定应压缩的MIME类型。包括常见的文本、CSS、JavaScript和JSON类型。

gzip_min_length

设置启用压缩的响应的最小长度(以字节为单位)。小文件受益不大,甚至可能由于压缩开销而变慢。

gzip_proxied

指示Nginx即使在代理响应时也进行压缩。any是常用值。

gzip_vary

向响应添加Vary: Accept-Encoding头,通知代理响应可能因Accept-Encoding请求头而异。

http {
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6; # 压缩级别1-9(6是良好平衡)
    gzip_buffers 16 8k; # 16个缓冲区,每个8KB
    gzip_http_version 1.1; # 压缩所需的最低HTTP版本
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
    gzip_min_length 1000; # 仅压缩大于1KB的响应
}

6. 优化日志记录

虽然日志对于监控和故障排除至关重要,但过多或未优化的日志记录会引入显著的磁盘I/O,尤其是在高流量网站上。

access_log

  • 禁用静态资源日志:对于频繁访问的静态内容(图像、CSS、JS),禁用access_log可以节省大量I/O。
  • 缓冲:Nginx可以将日志条目缓冲在内存中,然后再写入磁盘,从而减少磁盘写入频率。这里使用bufferflush参数。

error_log

设置适当的日志级别(criterrorwarninfodebug)。对于生产环境,warnerror通常足以捕获关键问题而不会淹没日志。

http {
    server {
        # 动态内容的默认访问日志
        access_log /var/log/nginx/access.log main;

        location ~* \.(jpg|jpeg|gif|png|css|js|ico|woff|woff2|ttf|svg|eot)$ {
            access_log off; # 禁用常见静态文件的日志记录
            expires 30d;
        }
    }

    # 主HTTP上下文的缓冲访问日志示例
    # access_log /var/log/nginx/access.log main buffer=16k flush=5s;
    error_log /var/log/nginx/error.log warn; # 仅记录警告及以上级别
}

7. 调整超时设置

适当配置的超时设置可以防止Nginx长时间占用非活动连接,从而释放资源。

客户端超时

  • client_body_timeout: Nginx等待客户端发送请求体的时间。
  • client_header_timeout: Nginx等待客户端发送请求头的时间。
  • send_timeout: Nginx等待客户端接受响应(发送后)的时间。

代理/FastCGI 超时 (如果适用)

  • proxy_connect_timeout: 与代理服务器建立连接的超时时间。
  • proxy_send_timeout: 向代理服务器传输请求的超时时间。
  • proxy_read_timeout: 从代理服务器读取响应的超时时间。
http {
    client_body_timeout 15s; # 客户端有15秒发送请求体
    client_header_timeout 15s; # 客户端有15秒发送请求头
    send_timeout 15s; # Nginx有15秒发送响应给客户端

    # 针对代理场景
    proxy_connect_timeout 5s; # 5秒连接上游服务器
    proxy_send_timeout 15s; # 15秒发送请求到上游服务器
    proxy_read_timeout 15s; # 15秒从上游服务器读取响应

    # 针对FastCGI场景
    fastcgi_connect_timeout 5s;
    fastcgi_send_timeout 15s;
    fastcgi_read_timeout 15s;
}

8. SSL/TLS 优化

对于启用HTTPS的网站,优化SSL/TLS设置对于减少CPU开销和提高握手性能至关重要。

ssl_session_cachessl_session_timeout

启用SSL会话缓存,以避免同一客户端后续连接的计算开销较大的完整TLS握手。

ssl_protocolsssl_ciphers

使用现代、强大的TLS协议(如TLSv1.2TLSv1.3)和安全的密码套件。使用ssl_prefer_server_ciphers on优先选择服务器密码。

ssl_stapling

启用OCSP Stapling,Nginx会定期从CA获取OCSP响应,并将其“装订”到SSL/TLS握手中。这通过避免单独的OCSP查询来减少客户端延迟。

server {
    listen 443 ssl;
    ssl_certificate /etc/nginx/ssl/your_domain.crt;
    ssl_certificate_key /etc/nginx/ssl/your_domain.key;

    ssl_session_cache shared:SSL:10m; # 共享缓存,用于10MB的会话数据
    ssl_session_timeout 10m; # 会话在10分钟后过期

    ssl_protocols TLSv1.2 TLSv1.3; # 使用现代、安全的协议
    ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256';
    ssl_prefer_server_ciphers on;

    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s; # 为OCSP查询指定DNS解析器
    resolver_timeout 5s;
}

9. 开放文件缓存

Nginx可以缓存频繁访问文件的文件描述符,减少重复的系统调用来打开和关闭文件。

open_file_cache

启用缓存,指定最大元素数量以及非活动元素保留的时间。

open_file_cache_valid

设置缓存检查其元素有效性的频率。

open_file_cache_min_uses

指定文件在inactive时间内必须被访问的最小次数,才能保留在缓存中。

open_file_cache_errors

确定Nginx是否应缓存打开文件时发生的错误。

http {
    open_file_cache max=100000 inactive=60s; # 缓存多达100,000个文件描述符,持续60秒
    open_file_cache_valid 80s; # 每80秒检查一次有效性
    open_file_cache_min_uses 1; # 缓存至少使用过一次的文件
    open_file_cache_errors on; # 缓存与文件打开相关的错误
}

总结

Nginx性能调优是一个持续的过程,而非一次性设置。这份清单为优化您的高流量网站提供了一个强大的起点。请记住,“完美”的配置很大程度上取决于您的特定应用程序、流量模式和服务器资源。在部署到生产环境之前,务必在预发布环境(staging environment)中测试所有更改,并持续使用Nginx Plus的实时活动监控、Prometheus、Grafana或基本系统工具(例如topiostatnetstat)监控您的Nginx实例和后端服务器。

通过细致地应用这些优化并根据您的环境进行调整,即使在最严苛的负载下,您也能确保Nginx以卓越的速度、效率和可靠性交付内容。