一、proxy_cache概述
proxy_cache是nginx中自带的模块,用于缓存响应,在未来的请求中将缓存的响应直接返回,加快响应速度。proxy_cache与proxy_pass联用,将源站的响应缓存下来,省去了再向源站发起请求的步骤。这个特性在高并发的场景下非常有用,可以大幅度减轻源站的压力。
为了让proxy_cache发挥出更好的效果,需要根据具体的情况对代理的配置做出优化,如设置cache有效时间、cache大小限制等。
二、proxy_cache清除
在代理缓存中,为了避免脏数据和缓存失效,需要定期清理缓存。
1、手动清除
# 清空所有缓存
$ nginx -s stop
$ rm -rf /var/cache/nginx/*
$ nginx
2、自动清除
可以通过定期删除缓存目录下的过期文件来实现自动清除。在nginx.conf中进行配置:
http {
proxy_cache_path /var/cache/nginx levels=1:2
keys_zone=my_cache:10m
inactive=60m;
proxy_cache_key "$scheme$request_method$host$uri$is_args$args";
server {
...
location / {
proxy_cache my_cache;
proxy_pass http://localhost:8000;
add_header X-Proxy-Cache $upstream_cache_status;
proxy_cache_valid 200 10m; # 如果响应状态码为200,则缓存在10分钟有效
proxy_cache_valid any 1m; # 如果响应状态码为非200,则缓存在1分钟有效
proxy_cache_bypass $http_pragma;
proxy_cache_revalidate on;
}
...
}
}
三、proxy_cache内存
proxy_cache数据可以存储在内存中,而不是磁盘上。这样做的优点是:读取速度更快,更适合缓存小文件或大量请求指向同一缓存的场景。默认情况下,nginx将缓存数据存储在磁盘上。
可以通过在CACHE_PATH中添加参数:proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m inactive=60m use_temp_path=off max_size=100m可配置最大内存缓存容量。
四、proxy_cache站群
proxy_cache在站群架构中有着非常重要的作用。在使用proxy_cache站群时,源站响应需要缓存到多个服务器上,从而实现更高效的读取。在nginx.conf中配置如下:
upstream backend {
server backend1.example.com:8080;
server backend2.example.com:8080;
...
server backendN.example.com:8080;
}
server {
...
location / {
proxy_cache my_cache;
proxy_pass http://backend;
add_header X-Proxy-Cache $upstream_cache_status;
}
...
}
五、proxy_cache valid
proxy_cache_valid指令用来控制响应缓存的有效时间。在nginx.conf中可配置具体的响应状态码的缓存时间。
proxy_cache_valid 200 1h; # 缓存状态码为200的响应1小时
proxy_cache_valid 404 1m; # 缓存状态码为404的响应1分钟
proxy_cache_valid 500 1s; # 缓存状态码为500的响应1秒
六、proxy_cache nginx
nginx本身也可以作为代理被缓存。可以通过子服务配置实现proxy cache。
proxy_cache_path /var/cache/nginx keys_zone=my_zone:10m;
server {
...
listen 8000;
proxy_cache my_zone;
proxy_pass http://localhost:9000;
...
}
七、proxy_cache清除批量
定期清理proxy cache是非常有必要的,但是对大型网站而言,手动清理的效率往往不能满足需求。
可以通过脚本实现nginx代理清除:
#!/bin/bash
# 缓存目录
cache_path=/var/cache/nginx
# 待删除的目录
remove_dirs=( $(find $cache_path/* -type d -mtime + 30) )
# 删除缓存目录下超时的缓存数据
for dir in ${remove_dirs[@]}
do
echo "removing cache in $dir"
rm -rf $dir/*
done
# 删除目录时,目录时完全匹配缓存项的key值,所以执行完之后需要调用一次proxy_cache_path指令
nginx -s reload
八、proxy_cache一直Miss
如果在配置中出现了proxy_cache一直miss的情况,考虑以下几点:
- 检查缓存目录是否存在,是否有可读写权限
- 检查传递给代理的响应是否正确,可以通过curl模拟http请求或使用tcpdump等抓包工具进行调试
- 检查proxy_cache_key是否正确,错误的代理键将导致缓存失效
- 检查proxy_cache_valid指令,响应状态码是否已正确指定
- 检查proxy_ignore_headers指令,是否包含响应头信息
通过上述方法进行排查,可以解决proxy_cache一直miss的问题,保持proxy_cache的有效性。