Nginx缓存配置实现CDN加速
- [1. 前言](#1. 前言)
- [2. 配置介绍](#2. 配置介绍)
-
- [2.1 proxy_cache_path](#2.1 proxy_cache_path)
- [2.2 proxy_cache](#2.2 proxy_cache)
- [2.3 proxy_cache_key](#2.3 proxy_cache_key)
- [2.4 proxy_cache_lock](#2.4 proxy_cache_lock)
- [2.5 proxy_cache_lock_timeout](#2.5 proxy_cache_lock_timeout)
- [2.6 proxy_cache_lock_age](#2.6 proxy_cache_lock_age)
- [2.7 proxy_cache_min_uses](#2.7 proxy_cache_min_uses)
- [2.8 proxy_cache_purge](#2.8 proxy_cache_purge)
- [2.9 proxy_cache_valid](#2.9 proxy_cache_valid)
- [3. 强制分片](#3. 强制分片)
- [4. 配置示例](#4. 配置示例)
- [5. 参考](#5. 参考)
1. 前言
Nginx缓存可以作为作为 CDN 节点实现访问文件的加速,可以极大减轻后端服务的带宽和机器负载。
本文介绍如何配置Nginx作为一个文件访问的缓存服务。
2. 配置介绍
2.1 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_key
MD5计算而来。
path
定义缓存的路径levels
定义缓存目录的深度,最多3层,例如:levels=1:2:2
, 定义每层目录使用的字母长度;cache_key计算的MD5是c/29/b7/f54b2df7773722d382f4809d65029c
,则缓存文件的相对路径是:c/29/b7/f54b2df7773722d382f4809d65029c
use_temp_path
是否使用临时目录keys_zone
活动密钥和数据信息都存储在一个共享内存区域中,name为名称,size为个数限制;inactive
在参数指定的时间内未访问的缓存数据将从缓存中删除。默认为10分钟;max_size
特殊的"缓存加载器"进程,设置的最大缓存大小,当超过该大小或可用空间不足时,它会删除最近最少使用的数据;min_free
最小可用空间量loader_files
启动一分钟后,特殊的"缓存加载器"进程被激活。它将有关文件系统上存储的先前缓存数据的信息加载到缓存区域中。加载也是以迭代方式完成的。在一次迭代中,最多loader_files加载 100 个项目(默认情况下为 100 个)loader_threshold
一次迭代的持续时间受参数限制 loader_threshold(默认情况下为 200 毫秒);
注意:该参数需要定义在
http
模块下,不
能定义在location
中。以下其他参数可以定义在location。
2.2 proxy_cache
conf
Syntax: proxy_cache zone | off;
Default: proxy_cache off;
其中zone就是用于缓存的共享内存区域,在 proxy_cache_path
中由keys_zone的name定义,同一个区域可以在多个地方使用。
2.3 proxy_cache_key
conf
Syntax: proxy_cache_key string;
Default: proxy_cache_key $scheme$proxy_host$request_uri;
定义缓存的键,例如:
proxy_cache_key "$host$request_uri $cookie_user";
默认情况下,该指令的值接近字符串:
proxy_cache_key $scheme$proxy_host$uri$is_args$args;
2.4 proxy_cache_lock
conf
Syntax: proxy_cache_lock on | off;
Default: proxy_cache_lock off;
启用后,每次只允许一个请求通过将请求传递到代理服务器,同一缓存元素的其他请求将等待响应出现在缓存中或释放此元素的缓存锁,最长不超过 proxy_cache_lock_timeout
指令设置的时间 。
2.5 proxy_cache_lock_timeout
conf
Syntax: proxy_cache_lock_timeout time;
Default: proxy_cache_lock_timeout 5s;
超时后,请求将被传递给代理服务器,但响应不会被缓存。
2.6 proxy_cache_lock_age
conf
Syntax: proxy_cache_lock_age time;
Default: proxy_cache_lock_age 5s;
设置的时间内,如果传递给代理服务器以填充新缓存元素的最后一个请求尚未完成,则可能会向代理服务器传递另一个请求。一般设置 <=
proxy_cache_lock_timeout 。
2.7 proxy_cache_min_uses
conf
Syntax: proxy_cache_min_uses number;
Default: proxy_cache_min_uses 1;
设置请求的数量达到一定次数之后响应将被缓存。
2.8 proxy_cache_purge
conf
Syntax: proxy_cache_purge string ...;
定义请求在何种条件下将被视为缓存清除请求,例如:
proxy_cache_purge PURGE
可通过 curl -X PURGE
进行对文件清除缓存。
2.9 proxy_cache_valid
conf
Syntax: proxy_cache_valid [code ...] time;
为不同的响应代码设置缓存时间,例如:
proxy_cache_valid 200 304 10m;
proxy_cache_valid 404 1m;
3. 强制分片
在以下场景下:
- 若是请求的文件大小1G,失败重试的代价稍微较大;
- 若是请求header使用了
Range: bytes=1024-2048
获取片段的场景;
可以在缓存的基础上,增加分片缓存,优势有:
- 当大文件缓存时,失败后减少重试的流量,只需要重试分片到后端服务;
- 也能解决后端代码框架 max_body_size 等类似的配置限制,通过分片从后端服务获取文件;
- 请求header携带Range时,不用获取整个原文件大小,减少对后端的请求;
若是支持强制分片,需要 ngx_http_slice_module 模块的支持。
该模块不是默认构建的,需要通过 --with-http_slice_module
配置参数启用。
示例:
location / {
slice 1m;
proxy_cache cache;
proxy_cache_key $uri$is_args$args$slice_range;
proxy_set_header Range $slice_range;
proxy_cache_valid 200 206 1h;
proxy_pass http://localhost:8000;
}
注意
:有如下配置是必须的:
proxy_cache_key
必须带上$slice_range
proxy_cache_valid
状态码缓存需要加上206
;proxy_set_header
新增或者改变,到后端的Range统一为slice的大小;
增加了 slice
也有一定的缺点
:
当使用
curl -X PURGE
请求文件地址清除缓存的时候,默认只清除第一个分片的缓存,需要前端增加curl -X PURGE -r 1048576-2097151
按照Range清除缓存。
其中Range 1048576-2097151
表示范围 1m-2m
,必须是 slice
值的倍数。
4. 配置示例
conf
http {
# ...
# 定义缓存路径、zone等
proxy_cache_path /data/proxycache levels=1:2:2 keys_zone=cache-hdd:1024m max_size=1024g inactive=48h use_temp_path=off;
server {
# 定义缓存使用的zone空间
proxy_cache cache-hdd;
location / {
# 强制启用 Accept-Ranges
proxy_force_ranges on;
# 强制分片
slice 100m;
proxy_set_header Range $slice_range;
# 缓存的key需要带上分片的range
proxy_cache_key "$uri$slice_range";
# 定义可以清除缓存
proxy_cache_purge PURGE;
# 文件访问了3次才将响应缓存下来
proxy_cache_min_uses 3;
# 对并发的请求,设置时间段内只发一个请求到后端
proxy_cache_lock on;
proxy_cache_lock_age 60s;
proxy_cache_lock_timeout 60s;
# 对不同状态码定义缓存时间
proxy_cache_valid 200 206 304 48h;
proxy_cache_valid 404 1s;
# 在header中增加 MISS/HIT 标识
add_header X-Cache-Status $upstream_cache_status;
# 代理到后端
proxy_pass http://domain;
}
}
}