Nginx | ngx_cache_purge 模块:实现清除特定上游服务(后端)响应缓存条目

知识是人生的灯塔,只有不断学习,才能照亮前行的道路

📢 大家好,我是 WeiyiGeek,一名深耕安全运维开发(SecOpsDev)领域的技术从业者,致力于探索DevOps与安全的融合(DevSecOps),自动化运维工具开发与实践,企业网络安全防护,欢迎各位道友一起学习交流、一起进步 🚀,若此文对你有帮助,一定记得点个关注⭐与小红星❤️或加入到作者知识星球『 全栈工程师修炼指南』,转发收藏学习不迷路 😋 。

Nginx 反向代理中清除特定的缓存条目

描述:前面几篇文章中《Nginx | HTTP 反向代理:对上游服务端响应缓存流程浅析与配置实践》、《Nginx | HTTP 反向代理:当缓存失效时如何减轻后端(上游)服务压力?》,作者介绍了反向代理中如何缓存上游响应,如何配置缓存过期策略,以及在缓存过期后如何使用陈旧缓存响应客户端。但是,在某些情况下,我们可能需要手动清除特定的缓存条目,例如在内容更新时或在特定条件下需要立即刷新数据。

那么如何在 Nginx 反向代理中清除特定的缓存条目?这将是本节要解决的问题。

实际上 Nginx 商业版本提供了 proxy_cache_purge 指令,用于清除特定的缓存条目。但是,在开源版本中,我们可以通过其他方式间接实现这一功能,例如使用第三方 ngx_cache_purge 找个扩展模块。

温馨提示:若文章代码块中存在乱码或不能复制,请联系作者,也可通过文末的阅读原文链接,加入知识星球中阅读,原文链接:https://articles.zsxq.com/id_6hpaidhf5l5s.html

ngx_cache_purge 模块是一个 Nginx 模块,它提供了清除 FastCGI、proxy、SCGI 和 uWSGI 缓存内容的能力,它 通过相同的共享内存区域和缓存key,在Nginx内部的红黑树结构中定位对应缓存项并删除。另外,由于是第三方模块,所以其需要在 Nginx 编译时通过 --add-module=./ngx_cache_purge/ 参数指定源码目录进行添加。

编译安装

首先,从 Github 中克隆 ngx_cache_purge 模块的代码到本地 /usr/local/src/ 目录中。

go 复制代码
$ cd /usr/local/src/
$ git clone --depth 1 https://github.com/FRiCKLE/ngx_cache_purge.git
$ ls ngx_cache_purge/
CHANGES  config  LICENSE  ngx_cache_purge_module.c  README.md  t  TODO.md

其次,编译安装 Nginx 并启用 ngx_cache_purge 模块。

go 复制代码
$ cd /usr/local/src/nginx-1.29.0/
$ ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --sbin-path=/usr/sbin/nginx --conf-path=/usr/local/nginx/conf/nginx.conf --pid-path=/usr/local/nginx/nginx.pid --error-log-path=/var/log/nginx/logs/error.log --http-log-path=/var/log/nginx/logs/access.log --lock-path=/var/run/nginx.lock --modules-path=/usr/local/nginx/modules --with-http_stub_status_module --with-http_realip_module --with-http_v2_module --with-http_ssl_module --add-module=/usr/local/src/ngx_cache_purge --with-cc-opt='-O2'
$ make && make install

指令参数

PROXY: proxy_cache_purge 配置指令,但是注意其在 location 块中使用时还有其它格式,即相同的指令名称。

go 复制代码
# 配置指令(相同位置语法)
syntax: proxy_cache_purge on|off|<method> [from all|<ip> [.. <ip>]]
default: none
context: http, server, location

# 配置指令(单独位置语法)
syntax: proxy_cache_purge zone_name key
default: none
context: location

# 使用方法

# 方式1,常用
http {
    proxy_cache_path  /tmp/cache  keys_zone=tmpcache:10m;
    server {
        location / {
          proxy_pass         http://127.0.0.1:8000;
          proxy_cache        tmpcache;
          proxy_cache_key    $uri$is_args$args;
      }

      location ~ /purge(/.*) {
          allow              127.0.0.1;
          deny               all;
          # 指定共享内存区域名(zone name)和key构造规则。
          proxy_cache_purge  tmpcache $1$is_args$args;
      }
    }
}

# 方式2,不常用了解即可。
http {
  proxy_cache_path  /tmp/cache  keys_zone=tmpcache:10m;
  server {
      location / {
        proxy_pass         http://127.0.0.1:8000;
        proxy_cache        tmpcache;
        proxy_cache_key    $uri$is_args$args;
        # 允许PURGE方法清除缓存,仅限本地IP
        proxy_cache_purge  PURGE from 127.0.0.1;
      }
  }
}

FastCGI, SCGI 和 uWSGI 缓存清除指令:

go 复制代码
# fastcgi_cache_purg
syntax: fastcgi_cache_purge on|off|<method> [from all|<ip> [.. <ip>]]
default: none
context: http, server, location

syntax: fastcgi_cache_purge zone_name key
default: none
context: location

# scgi_cache_purge
syntax: scgi_cache_purge on|off|<method> [from all|<ip> [.. <ip>]]
default: none
context: http, server, location

syntax: scgi_cache_purge zone_name key
default: none
context: location

# uwsgi_cache_purge
syntax: uwsgi_cache_purge on|off|<method> [from all|<ip> [.. <ip>]]
default: none
context: http, server, location

syntax: uwsgi_cache_purge zone_name key
default: none
context: location

从 ngx_cache_purge 项目 Readme 文档中可以看到,在清除指定缓存键时,清除请求所使用的缓存key必须与原始缓存生成时完全一致,包括协议scheme、主机host、URI路径、查询参数args等所有变量,若不同location中变量取值不一致,则无法匹配到正确的缓存条目,这一点需要特别注意。

实践演示

步骤 01.在 Nginx 服务器上配置两个监听 8010 和 8011端口用于模拟上游服务器,并使用 upstream 模块定义上游服务器组。

go 复制代码
# 创建一个测试文件
echo"https://www.weiyigeek.top" >> /usr/local/nginx/html/url.txt

# 创建上游服务器配置文件
tee backend_server.conf <<'EOF'
upstream backend_server {
# 定义共享内存区,用于在工作进程间同步负载信息,可根据后端服务器数量调整。
  zone backend_zone 64k;

# 指定多个上游服务组,缺省使用轮询负载均衡算法
  server 10.20.172.214:8010;
  server 10.20.172.214:8011;

# 设置与上游服务器的长连接,最多保持10个空闲的保活连接。
  keepalive 10;
  keepalive_timeout 60s; # 设置与上游服务器的长连接,空闲连接的超时时间。
}

# 模拟上游服务器其监听端口为8010
server {
  listen 8010;
# 任意主机名
  server_name _;
# 设置字符集为utf-8
  charset utf-8;
# 设置默认响应类型为文本
  default_type text/plain;
# 根目录
  location / {
    root  /usr/local/nginx/html;
    index index.html;
  }
# 模拟api接口响应
  location ^~ /api {
    return 200 '$time_iso8601 $request_id $server_addr:$server_port $request_uri\n';
  }
}

# 模拟上游服务器其监听端口为8011
server {
  listen 8011;
  server_name _;
  charset utf-8;
  default_type text/plain;

  location / {
    root  /usr/local/nginx/html;
    index index.html;
  }

  location ^~ /api {
    return 200 '$time_iso8601 $request_id $server_addr:$server_port $request_uri\n';
  }
}
EOF

步骤 02.在 Nginx 服务器上配置缓存路径以及反向代理,并启用缓存策略。

go 复制代码
tee test.conf <<'EOF'
# 定义缓存路径,为 data01 缓存区域分配10MB内存空间,加载缓存索引文件,并设置最大内存使用限制为128MB,删除10分钟内不活跃的缓存条目。
proxy_cache_path /usr/local/nginx/cache levels=2:2 keys_zone=data01:10m loader_threshold=300 loader_files=200 max_size=128m inactive=10m;

# 虚拟主机配置,反向代理到上游服务器组
server {
  listen 80;
  server_name test.weiyigeek.top;
  charset utf-8;
  default_type text/html;

# 启用 HTTP/2 支持
  http2 on;

# 日志文件
  access_log /var/log/nginx/test.log main;
  error_log /var/log/nginx/test.err.log debug;

# 缓存管理端点(可选,用于清除缓存)
  location ~ /purge(/.*) {
    allow 127.0.0.1;
    allow 10.20.172.0/24;
    deny all;
    # proxy_cache_purge data01 "$scheme$request_method$host$1$is_args$args";
    # 特别注意:键规则需要与proxy_cache_key保持一致,否则无法清除缓存。
    proxy_cache_purge data01 $scheme$request_method$http_host$1;
  }

  location / {
    proxy_pass http://backend_server;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    # 启用缓存,指定缓存区域为 data01
    proxy_cache data01;
    # 自定义缓存KEY
    proxy_cache_key $scheme$request_method$http_host$uri;
    # 响应码为200的响应数据进行缓存有效期为5分钟
    proxy_cache_valid 200 5m;
    # 自定义响应头,用于验证上游缓存状态
    add_header X-Cache-Status $upstream_cache_status;
  }
}
EOF

步骤 03.验证配置并重启 Nginx 服务,使用 curl 验证缓存功能。

go 复制代码
# 验证&重启
nginx -t && nginx -s reload

# 请求两次 api 接口,观察 X-Cache-Status 响应头变化,验证缓存是否生效。
$ curl -i http://test.weiyigeek.top/api

HTTP/1.1 200 OK
Server: nginx/1.29.0
Date: Fri, 26 Dec 2025 15:08:59 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 83
Connection: keep-alive
X-Cache-Status: HIT

2025-12-26T23:08:53+08:00 97cb180d3e4c79d120d5fc92a8d92eed 10.20.172.214:8010 /api

# 同样的请求,观察 X-Cache-Status 响应头变化,验证缓存是否生效。
$ curl -i http://test.weiyigeek.top/url.txt
HTTP/1.1 200 OK
Server: nginx/1.29.0
Date: Fri, 26 Dec 2025 15:09:07 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 26
Connection: keep-alive
Last-Modified: Fri, 26 Dec 2025 15:05:11 GMT
ETag: "694ea427-1a"
X-Cache-Status: HIT
Accept-Ranges: bytes

https://www.weiyigeek.top

# 最后,查看缓存目录,验证缓存文件是否生成。
tree /usr/local/nginx/cache

weiyigeek.top-验证反向代理缓存图

步骤 04.使用 curl 传递要清除的缓存目标文件,并验证是否已经清除缓存。

go 复制代码
# 首先,清除 api 接口缓存
$ curl http://test.weiyigeek.top/purge/api -i
HTTP/1.1 200 OK
Server: nginx/1.29.0
Date: Fri, 26 Dec 2025 16:22:22 GMT
Content-Type: text/html
Content-Length: 291
Connection: keep-alive

<html>
<head><title>Successful purge</title></head>
<body bgcolor="white">
<center><h1>Successful purge</h1>
<br>Key : httpGETtest.weiyigeek.top/api
<br>Path: /usr/local/nginx/cache/20/d6/ccedcfc4a81815eda1e8a8d7a1a9d620
</center>
<hr><center>nginx/1.29.0</center>
</body>
</html>

# 其次,清除 url.txt 缓存文件
$ curl http://test.weiyigeek.top/purge/url.txt -i
HTTP/1.1 200 OK
Server: nginx/1.29.0
Date: Fri, 26 Dec 2025 16:23:03 GMT
Content-Type: text/html
Content-Length: 295
Connection: keep-alive

<html>
<head><title>Successful purge</title></head>
<body bgcolor="white">
<center><h1>Successful purge</h1>
<br>Key : httpGETtest.weiyigeek.top/url.txt
<br>Path: /usr/local/nginx/cache/76/78/847937bd0ff20f9c81f5cc853ff67876
</center>
<hr><center>nginx/1.29.0</center>
</body>
</html>

weiyigeek.top-使用ngx_cache_purge第三方模块清除缓存图

至此,我们已经完成了 Nginx 缓存清除功能的配置和验证,大家也赶快上手实践吧!

END

加入:作者【全栈工程师修炼指南】知识星球

『 全栈工程师修炼指南』星球,主要涉及全栈工程师(Full Stack Development)实践文章,持续更新包括但不限于企业SecDevOps和网络安全等保合规、安全渗透测试、编程开发、云原生(Cloud Native)、物联网工业控制(IOT)、人工智能Ai,从业书籍笔记,人生职场认识等方面资料或文章。

Q: 加入作者【全栈工程师修炼指南】星球后有啥好处?

✅ 将获得作者最新工作学习实践文章以及网盘资源。

✅ 将获得作者珍藏多年的全栈学习笔记(需连续两年及以上老星球友,也可单次购买)

✅ 将获得作者专门答疑学习交流群,解决在工作学习中的问题。

✅ 将获得作者远程支持(在作者能力范围内且合规)。

获取:作者工作学习全栈笔记

作者整理了10年的工作学习笔记(涉及网络、安全、运维、开发),需要学习实践笔记的看友,可添加作者微信或者回复【工作学习实践笔记】,当前价格¥299,除了获得从业笔记的同时还可进行问题答疑以及每月远程技术支持,希望大家多多支持,收获定大于付出!

知识推荐 往期文章

若文章对你有帮助,请将它转发给更多的看友,若有疑问的小伙伴,可在评论区留言你想法哟 💬!

相关推荐
難釋懷1 天前
Redis命令-Set命令
数据库·redis·缓存
编程小风筝1 天前
Spring 框架如何整合Redis缓存中间件?
redis·spring·缓存
hunter14501 天前
Linux 进程与计划任务
linux·运维·服务器
楼田莉子1 天前
Linux学习之磁盘与Ext系列文件
linux·运维·服务器·c语言·学习
陌上花开缓缓归以1 天前
linux 怎么模拟系统panic重启
linux·运维·服务器
月白风清江有声1 天前
vscode使用git
linux·运维·服务器
光明顶上的5G1 天前
本地缓存面试重点
java·缓存·面试
haluhalu.1 天前
深入理解Linux线程机制:线程概念,内存管理
java·linux·运维
JavaLearnerZGQ1 天前
我的Redis笔记2【分布式缓存】
redis·笔记·缓存
cui__OaO1 天前
Linux驱动--驱动编译
linux·运维·服务器