为什么需要极限调优?

512MB 内存的服务器,Nginx 必须精打细算。默认配置下 Nginx 会消耗不必要的内存,通过针对性优化,可以将内存占用从 100MB+ 降到 30-50MB,同时保持高并发性能。

完整配置方案

全局配置 (nginx.conf)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
user www-data;
worker_processes 2;           # 精确匹配CPU核心数
worker_rlimit_nofile 1024;    # 文件描述符上限
pid /run/nginx.pid;

events {
    worker_connections 512;    # 每个worker最大连接数
    use epoll;                 # Linux高性能事件模型
    multi_accept on;           # 一次接受所有新连接
    accept_mutex off;          # 减少锁争用
}

http {
    # 基础优化
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 30;
    keepalive_requests 1000;
    reset_timedout_connection on;

    # 缓冲区 - 小内存关键
    client_body_buffer_size 1K;
    client_header_buffer_size 1K;
    client_max_body_size 2m;
    large_client_header_buffers 2 1K;
    output_buffers 1 16k;
    postpone_output 1460;

    # 压缩
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 4;         # 4是压缩率和CPU的平衡点
    gzip_min_length 256;
    gzip_types
        text/plain
        text/css
        application/json
        application/javascript
        text/xml
        application/xml
        application/xml+rss
        text/markdown
        image/svg+xml;

    # 日志 - 减少IO
    access_log off;            # 静态站不需要访问日志
    error_log /var/log/nginx/error.log warn;

    # 连接限制
    limit_conn_zone $binary_remote_addr zone=connlimit:1m;
    limit_conn connlimit 20;

    # 速率限制
    limit_req_zone $binary_remote_addr zone=ratelimit:1m rate=10r/s;
    limit_req zone=ratelimit burst=20 nodelay;

    # 隐藏版本号
    server_tokens off;

    include /etc/nginx/sites-enabled/*;
}

站点配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
server {
    listen 80;
    server_name airef.dev www.airef.dev;
    return 301 https://airef.dev$request_uri;
}

server {
    listen 443 ssl http2;
    server_name airef.dev;

    # SSL 最小内存配置
    ssl_certificate /etc/letsencrypt/live/airef.dev/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/airef.dev/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout 1h;
    ssl_session_tickets off;
    ssl_stapling on;
    ssl_stapling_verify on;

    # 安全头
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
    add_header X-Content-Type-Options nosniff always;
    add_header X-Frame-Options DENY always;
    add_header Referrer-Policy strict-origin-when-cross-origin always;

    # 根目录
    root /var/www/airef.dev/public;
    index index.html;

    # AI发现文件
    location = /llms.txt {
        default_type text/plain;
        add_header Cache-Control "public, max-age=3600";
    }
    location = /llms-full.txt {
        default_type text/plain;
        add_header Cache-Control "public, max-age=3600";
    }
    location = /robots.txt {
        default_type text/plain;
        add_header Cache-Control "public, max-age=86400";
    }
    location = /sitemap.xml {
        default_type application/xml;
        add_header Cache-Control "public, max-age=3600";
    }
    location = /feed/ {
        default_type application/rss+xml;
        add_header Cache-Control "public, max-age=3600";
    }

    # 静态资源 - 强缓存
    location ~* \.(css|js|svg|png|jpg|webp|woff2|ico)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
        try_files $uri =404;
    }

    # HTML页面 - 短缓存
    location ~* \.html$ {
        expires 1h;
        add_header Cache-Control "public, must-revalidate";
        try_files $uri $uri.html $uri/index.html =404;
    }

    # 其他请求
    location / {
        limit_req zone=ratelimit burst=20 nodelay;
        try_files $uri $uri/ $uri.html $uri/index.html =404;
    }

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

内存监控脚本

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#!/bin/bash
# /usr/local/bin/nginx-mem-monitor.sh
THRESHOLD=80  # MB

NGINX_MEM=$(ps -C nginx -o rss= | awk '{sum+=$1} END {printf "%.0f", sum/1024}')

if [ "$NGINX_MEM" -gt "$THRESHOLD" ]; then
    echo "WARNING: Nginx memory usage ${NGINX_MEM}MB exceeds ${THRESHOLD}MB"
    # 可选:自动重启
    # sudo systemctl restart nginx
fi

echo "$(date): Nginx memory: ${NGINX_MEM}MB" >> /var/log/nginx/memory.log

性能对照表

配置项 默认值 优化值 内存节省
worker_processes auto 2 ~50MB
worker_connections 1024 512 ~30MB
access_log on off ~20MB
client_body_buffer 16K 1K ~15MB
gzip_comp_level 6 4 CPU减半
ssl_session_cache 1m 效果显著

关键提醒

在 512MB 服务器上,关闭 access_log 是最大的内存优化之一。静态站点不需要逐请求日志,改用 GoAccess 分析离线日志即可。这个调整可以节省约 20MB 的缓冲区内存。