您的位置:

深入理解proxy_cache

一、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的有效性。