Nginx 缓存介绍
Nginx 的 ngx_http_proxy_module
模块,除了提供请求转发,还提供了请求缓存的能力。当开启缓存功能时,Nginx 会将请求响应缓存到本地磁盘上,后续的请求,只要满足缓存条件,就会直接返回缓存内容,Nginx 不会再将请求转发到后端服务。
使用缓存功能需要两步,首先配置 proxy_cache_path
参数,指定缓存文件的存放地址等信息,`proxy_cache_path 语法如下:
proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [min_free=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
proxy_cache_path 有两个必填参数:path 和 keys_zone
- path:配置的是本机文件的路径,做为共享内存缓存区,响应将会被缓存到该路径下
- keys_zone:指定内存缓冲区的名称和大小
http {
#...
proxy_cache_path /data/nginx/cache keys_zone=mycache:10m;
}
第二步则是配置缓存的使用规则,在 server 下加入以下配置:
server {
listen 80;
server_name xx.com;
location / {
proxy_pass http://172.18.1.1:8080;
proxy_cache mycache;
proxy_cache_valid 200 10m;
proxy_cache_methods GET OPTIONS;
}
}
proxy_cache:指定内存共享缓冲区,这里我们用第一步配置的keys_zone
proxy_cache_valid:定义不同响应码的缓存时间,这里对 200 的响应进行缓存,缓存时间为 10 分钟
proxy_cache_methods:需要缓存的方法,这里我们只缓存 GET 跟 OPTIONS 请求
最后执行 nginx -s reload
重新加载配置文件,缓存的配置就完成了。现在所有 200 的 GET/OPTIONS 请求会被 Nginx 缓存到服务器的 /data/nginx/cache
目录下,过期时间为 10 分钟,后面相同的请求不会转发到后端,而是直接读取缓存中的值进行返回。
验证
172.18.1.1上新建test.txt,GET访问后修改test.txt内容再次访问。
清除缓存
ngx_http_proxy_module 没有提供缓存清除的功能,可以通过手动删除缓存目录的方法删除 nginx 缓存,但这种方式比较麻烦,而且只能删除整个缓存(当然也可找到特定的请求,针对特定的请求进行删除,但是很难找出来)
这里介绍另外一种方法,通过第三方模块 ngx_cache_purge 实现缓存清除功能,ngx_cache_purge 是第三方模块,需要编译 nginx 的时候手动引入。
ngx_cache_purge地址:https://github.com/FRiCKLE/ngx_cache_purge#sample-configuration-separate-location-syntax
ngx_cache_purge的使用很简单,只需要在对用的 location 下配置多下面这两个参数:
proxy_cache_key $uri$is_args$args;
proxy_cache_purge PURGE from all;
完整配置:
server {
listen 80;
server_name xxx.com;
location / {
proxy_pass http://172.18.1.1:8080;
proxy_cache hxy;
proxy_cache_valid 200 10m;
proxy_cache_methods GET OPTIONS;
proxy_cache_key $uri$is_args$args;
proxy_cache_purge PURGE from all;
}
}
proxy_cache_key:缓存请求的 key,默认为请求的路径。这是什么意思呢?nginx 在接收到请求的时候,会将请求的信息组装成 key,响应内容作为 value,存放到共享缓存下,这里配置的是$uri$is_args$args,如果我请求 http://xxx.com/test.txt,然后查看共享缓存目录下的文件,就能看到该请求的 key 了
$ cat /data/nginx/cache/7a228ef0dbbc11e417815a77eca5f0bc
vb&e&eK&e(Ǧj3""278D547841EA7EC355ECC0E61B316C0E"
KEY: /test.txt
HTTP/1.1 200 OK
Server: AliyunOSS
Date: Wed, 11 Oct 2023 07:13:10 GMT
Content-Type: text/plain
Content-Length: 37
Connection: close
x-oss-request-id: 65264B062AA9763539897758
Accept-Ranges: bytes
ETag: "278D547841EA7EC355ECC0E61B316C0E"
Last-Modified: Wed, 11 Oct 2023 06:59:15 GMT
x-oss-object-type: Normal
x-oss-hash-crc64ecma: 17353918042953165731
x-oss-storage-class: Standard
Content-MD5: J41UeEHqfsNV7MDmGzFsDg==
x-oss-server-time: 1
cache_key 为 /test.txt
proxy_cache_purge:配置缓存删除的策略,语法为 proxy_cache_purge on|off|<method> [from all|<ip> [.. <ip>]]
,这里我们配置为PURGE from all,意思是允许所有 ip 发起 PURGE 请求对缓存进行删除。
现在,我们要删除 text.txt 的缓存,只需要发起一个 PURGE 请求即可
$ curl -X PURGE http://huangxy.com/test.txt
<html>
<head><title>Successful purge</title></head>
<body bgcolor="white">
<center><h1>Successful purge</h1>
<br>Key : /test.txt
<br>Path: /data/nginx/cache/7a228ef0dbbc11e417815a77eca5f0bc
</center>
<hr><center>nginx/1.21.6</center>
</body>
</html>