Nginx反向代理与缓存优化实战:给网站装上加速引擎

Nginx反向代理与缓存优化实战:给网站装上加速引擎

作为草根站长,手头可能只有一台低配 VPS,却要跑好几个网站。如果每个站点都直接暴露在公网上,不仅资源消耗大,安全性也是隐患。用 Nginx 做反向代理加缓存层,是我这些年压榨服务器性能最有效的方案。

什么是反向代理

反向代理就是让 Nginx 作为中间人,接收用户的请求,然后转发给后端真实的 Web 服务器(Apache、PHP-FPM、Node.js 等),再把后端返回的结果回传给用户。用户全程只跟 Nginx 打交道,看不到后端的存在。

这样做有三个明显的好处:第一,后端服务被隐藏起来,减少了攻击面;第二,Nginx 处理静态文件和并发连接的能力远超 Apache,能大幅提升吞吐量;第三,可以在代理层统一做 SSL 卸载、缓存、限流、日志等工作。

基础反向代理配置

先看一个最基础的反向代理配置,把 Nginx 放在 Apache 前面:

server {
    listen 80;
    server_name example.com;

    location / {
        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;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

这里 proxy_pass 指定了后端地址,后面几个 proxy_set_header 的作用是把用户真实信息透传给后端。如果不传 X-Real-IP,后端看到的 IP 永远是 127.0.0.1,日志和限制都会失效。

开启缓存层

纯代理只能解决隐藏后端的问题,对性能提升有限。真正让网站起飞的是缓存。Nginx 的 proxy_cache 功能可以把后端返回的页面缓存到磁盘上,同样的请求直接返回缓存,不再请求后端。

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

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_cache mycache;
        proxy_cache_key "$scheme$request_method$host$request_uri";
        proxy_cache_valid 200 302 60m;
        proxy_cache_valid 404 1m;
        proxy_cache_use_stale error timeout updating http_500 http_502 http_503;
        proxy_cache_background_update on;

        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;
    }
}

解释一下关键参数:

  • keys_zone=mycache:10m:分配 10MB 共享内存用来缓存索引键,大约可以管理 8 万个键。
  • max_size=1g:缓存文件总大小上限 1GB,超过后 Nginx 会自动清理最少使用的缓存。
  • inactive=60m:缓存文件如果 60 分钟没有被访问,就会自动删除。
  • proxy_cache_valid:对不同 HTTP 状态码设置缓存有效期。200 和 302 缓存 60 分钟,404 只缓存 1 分钟。
  • proxy_cache_use_stale:后端宕机或出错时,允许返回过期的缓存。这对提高可用性非常重要。

按需清除缓存

缓存最头疼的问题就是更新。文章发布后,首页和分类页的缓存还是旧的。解决办法是安装 ngx_cache_purge 模块,然后配置一个清除缓存的接口:

location ~ /purge(/.*) {
    allow 127.0.0.1;
    allow 你的IP;
    deny all;
    proxy_cache_purge mycache "$scheme$request_method$host$1";
}

然后在发布文章时,用 curl 请求一下要清除的 URL 即可:

curl -s http://127.0.0.1/purge/
curl -s http://127.0.0.1/purge/article/123.html

SSL 卸载

在代理层统一处理 HTTPS,后端只跑 HTTP,能让配置简化很多:

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;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header X-Forwarded-Proto https;
        # 缓存配置同上
    }
}

用 Certbot 自动续期证书,配合上面的代理,就能轻松跑满 A+ 评分。

动静分离

把静态资源(图片、CSS、JS)直接交给 Nginx 处理,不走后端:

location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2)$ {
    expires 30d;
    add_header Cache-Control "public, immutable";
    # 直接读取文件系统,不经过代理
    root /var/www/html;
    access_log off;
}

这套配置能让后端压力减少 80% 以上。我的博客之前 Apache 平均负载在 2.5 左右,套上 Nginx 缓存加动静分离后,负载降到了 0.3。

常见问题

后端获取不到真实 IP

确认代理配置中传了 X-Real-IPX-Forwarded-For 头,并且后端的日志格式使用了真实 IP 变量。对于 PHP 应用,还需要设置:

fastcgi_param HTTP_X_REAL_IP $remote_addr;

缓存没有命中

检查 proxy_cache_key 是否包含了 $request_method,有时候 POST 请求也会被缓存导致奇怪的问题。另外确认缓存目录的权限是否正确。

代理超时

后端响应慢时,Nginx 默认 60 秒超时。对于长耗时的操作,可以适当调大:

proxy_connect_timeout 30s;
proxy_read_timeout 120s;
proxy_send_timeout 60s;

总结

Nginx 反向代理加缓存是草根站长性价比最高的性能优化方案。不需要升级服务器配置,只需要花点时间调整 Nginx 配置,就能让网站速度提升一个档次。上面给出的配置已经在我自己的多台 VPS 上稳定运行了两年多,值得收藏尝试。

实际部署时建议先在一台测试站点上验证缓存策略,观察一段时间的命中率和后端负载,再逐步推广到所有站点。缓存虽好,但过期策略不当会让用户看到旧内容,反而影响体验。

Last modification:July 14th, 2026 at 08:24 am

Leave a Comment