上一篇文章讲了 Nginx 作为代理服务的使用方式, 这篇文章我们讲一讲 Nginx 作为缓存服务是怎么工作的, 以及实战的使用.
先看一张图:
面对第一次客户端的应用 Nginx 需要从后端的服务获取数据, 对于后续的请求, Nginx 若进行了缓存就不再从后端服务获取数据.
1.proxy_cache 实战
1.1proxy_cache_path
语法: proxy_cache_path path [levels=levels]. 只能用在 http 中.
proxy_cache_path /root/cache levels=1:2 keys_zone=zzm_cache:10m max_size=1g inactive=60m use_temp_path=off;
/root/cache: 定义 proxy_cache 生成文件的根路径
levels: 默认所有缓存文件都放在上面指定的根路径中, 从而可能影响缓存的性能. 推荐指定为 2 级目录来存储缓存文件
key_zone: 这个的值是字符串, 可以随意写. 用于在共享内存中定义一块存储区域来存放缓存的 key 和 metadata(类似于使用次数), 这样 nginx 可以快速判断一个 request 是否命中缓存. 1m 可以存储 8000 个 key,10m 可以存在 80000 个 key
max_size: 最大 cache 空间. 如果不指定, 会使用掉所有 disk space. 当达到 disk 上限后, 会删除最少使用的 cache
inactive: 内存中缓存的过期检查周期. 示例配置中如果 1h 内都没有被访问, 则不论状态是否为 expired, 都会清除缓存. 需要注意的是, inactive 和 expired 配置项的含义是不同的, expired 只是判断过期时间, 不会删除缓存; 而 inactive 是直接删除过期缓存
use_temp_path: 如果为 off, 则 nginx 会将缓存文件直接写入指定的 cache 文件中, 而不使用 temp_path 指定的临时存储路径
1.2proxy_cache
proxy_cache zone | off. 默认是关闭的, 可以用在 http,server,location 中.
- location / {
- proxy_cache zzm_cache;
- proxy_pass http://zzm;
- proxy_cache_valid 200 304 12h;
- proxy_cache_valid any 10m;
- proxy_cache_key $host$uri$is_args$args;
- add_header Nginx-Cache "$upstream_cache_status";
- proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
- }
proxy_cache: 对应 http 段的 key_zone, 是你定义的 proxy_cache 所使用的共享空间的名称, 我在 1.1 中定义的是 zzm_cache, 所以在这里也写的是 zzm_cache.
proxy_cache_valid: 对指定的 HTTP 状态进行缓存, 并指定缓存时间. 可以自定义写入多个配置项. 这里我们对 200 和 304 的返回码缓存 12 小时. 其余的缓存 10 分钟
proxy_cache_key: 缓存的维度
is_args: 如果 $args 设置, 值为 "?", 否则为 ""
proxy_next_upstream 当请求服务器发生错误或超时时, 会尝试到下一台服务器
1.3 编写后端服务
SpringBoot
访问 zzm 这个路径的时候, 会返回配置文件中的 spring.s 项, 具体值可以参考我们的启动设置:
启动 3 个后台进程
三个后台金正分别对应 6000 端口, 6001 端口, 6002 端口
1.4 配置 upstream
- upstream zzm{
- server 127.0.0.1:6000;
- server 127.0.0.1:6001;
- server 127.0.0.1:6002;
- }
所以我们访问 ip:port/zzm 的时候会自动去访问后台
1.5 效果展示:
我们首先注释掉 proxy_cache zzm_cache; 进行访问, 也就是没有缓存的情况下, 访问 3 次:
第一次结果
第二次结果
第三次结果
我们可以看到没有缓存的情况下, 会进行轮询访问, 每次访问的结果不一样, 而且我们的缓存路径什么都没有, 让我想起了一首歌空空如也:
缓存路径
接下来我们把缓存打开, 访问 3 次, 只会有下面这个页面:
访问 3 次都是这个页面
同时缓存路径有了变化:
发现多了两个目录
好奇的看了下目录下的文件内容:
缓存的文件内容
我们可以看到 6000 值被缓存下来了, 同时 key 就是我们在浏览器敲击的 url, 所以我们可以大胆猜想第二次访问的时候就是从这个文件里面把相关的数据拿出来的.
1.6 缓存扩展
1.6.1 如何清空缓存
1.6.1.1 直接 rm 缓存目录下所有的文件, 但这样会干掉所有的缓存
1.6.1.2 使用 ngx_cache_purge
1.6.2 如何让部分页面不缓存
1.6.2.1proxy_no_cache string 可以在 http,server,location 中配置
proxy_no_cache 使用
当我们再次访问 http://47.100.199.15/zzm 时, 发现不会再缓存了. 这里的配置文件中我写了很多变量, 只要其中一个变量不为 0, 这个 url 就不会被缓存.
1.7 缓存命中分析
1.7.1 方式一: 通过设置 response 的头信息 Nginx-Cache
add_header Nging-Cache "$upstream_cache_status";
upstream_cache_status
当我们没有缓存的时候, 我们可以看到应答会是 MISS:
MISS
如果缓存了:
HIT
1.7.2 方式二: 通过设置 log_format, 打印日志分析
现在 nginx.conf 中加入新的配置项:
nginx.conf
此时我们怒刷前端页面, 会发现后端日志如下:
access.log
Nginx 的缓存服务就讲到这里, 欢迎大家指正
来源: http://www.jianshu.com/p/5659e74ab81e