nginx proxy_cache

Nginx自带缓存,实现动静分离的分层架构。

nginx自己有单独的进程来对磁盘上的缓存文件进行扫描,在内存中建立缓存索引。并且有管理进程来对缓存进行过期判断,更新等操作

基本配置

首先需要在http内声明缓存配置

1
2
3
http {
proxy_cache_path /dev/shm/nginx/ngx_cache_one levels=1:2 keys_zone=ngx_cache_one:10m inactive=5m max_size=200m;
}

指令参数说明:

  • proxy_cache_path: 缓存文件路径
  • levels: 一般最多三级,这里指定二级,第一级目录一个字符命名,第二级有两个字符命名(总共含有161616=4096个文件目录)
  • keys_zone: 设置缓存名称 和 存储在内存中的元数据的大小
  • inactive: 在指定时间内没人访问则被删除
  • max_size: 最大缓存空间,如果缓存空间满,默认覆盖掉缓存时间最长的资源

接下来需要配置 nginx vhost server

1
2
3
4
5
6
7
8
9
10
11
12
server {
location /post {
add_header Nginx-Cache $upstream_cache_status;
proxy_cache ngx_cache_one;
proxy_cache_valid 200 206 304 301 302 2m;
proxy_cache_key $uri;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8080;
}
}

配置项介绍:

  • proxy_cache: 使用名为ngx_cache_one的缓存配置
  • proxy_cache_valid: 成功响应的缓存时间
  • proxy_cache_key: 定义缓存唯一key,通过唯一key来进行hash存取(缓存文件名为md5($uri))
  • proxy_set_header: 自定义http header头,用于发送给后端真实服务器
  • proxy_pass: 缓存如未命中,则代理到的后端服务器

过期指令优先级排序:
inactvie > 源服务器端Expires、源服务器端max-age > proxy_cache_valid

进阶配置

主动清理缓存

需要用到的 proxy_cache_purge 指令与 proxy_cache 相反。

1
2
3
4
5
6
7
server {
location /purge(/.*) {
allow 127.0.0.1; //只允许本机访问
deny all; //禁止其他所有ip
proxy_cache_purge ngx_cache_one $host$1; //清理缓存
}
}

proxy_cache_purge 指令的第一个参数就是 proxy_cache_path 中指定的 keys_zone

通过软链接扩容目录磁盘空间

1
> ln -s /bak/test/cache/0 /dev/shm/nginx/cache/0

支持客户端Range请求(断点续传)

当缓存代理转发http请求到后端服务器时,http header会改变,header中的部分参数,会被取消掉。其中range参数被取消,导致,后端nginx服务器没有收到range参数,最终导致这个分片下载不成功。所以需要对代理转发的header进行配置。

为了确保range请求下,proxy_cache_key的唯一性,需要引入$http_range

1
2
3
4
5
6
7
8
9
10
11
12
13
server {
location /post {
add_header Nginx-Cache $upstream_cache_status;
proxy_cache ngx_cache_one;
proxy_cache_valid 200 206 304 301 302 2m;
proxy_cache_key $http_range$uri;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Range $http_range;
proxy_pass http://127.0.0.1:8080;
}
}

相关链接