Web内容缓存

  • 来源:新网
  • 更新日期:2018-04-18

摘要:当缓存被启用时,Nginx保存响应到磁盘缓存并每次请求相同的内容时不用代理请求使用它们响应客户端。

1 介绍

当缓存被启用时,Nginx保存响应到磁盘缓存并每次请求相同的内容时不用代理请求使用它们响应客户端。

2 启用响应缓存

t01dcd344c153d16d28.jpg

为了启用缓存,在http上下文设置proxy_cache_path指令。第一个强制参数是缓存内容的本地文件系统,强制参数keys_zone定义用于存储缓存条目的元数据的共享内存区域的名称和大小:

http {

...

proxy_cache_path /data/nginx/cache keys_zone=one:10m;

}

然后在你想要缓存服务器响应的上下文(协议类型、虚拟主机或location)中使用proxy_cache指令,指定proxy_cache_path指令的keys_zone参数定义的区域名称(在这种情况下,是one):

http {

...

proxy_cache_path /data/nginx/cache keys_zone=one:10m;

 

server {

proxy_cache one;

location / {

proxy_pass http://localhost:8000;

}

}

}

注意,keys_zone参数定义的大小不限制缓存响应数据的总大小。缓存响应自身有一个元数据备份存储文本系统上的特定文件中。为了限制缓存响应数据的总大小,使用proxy_cache_path指令的max_size参数。(但是注意,缓存数据的总大小可以临时超过这个限制)

3 涉及缓存的Nginx进程

有两个额外的Nginx进程涉及缓存:

缓存管理器定期被激活检查缓存的状态。如果缓存大小超过proxy_cache_path指令的max_size参数设置的限制,缓存管理器删除数据最近访问的数据。如前所述,大多数缓存数据能在缓存管理器激活期间临时超过限制。

Nginx启动之后,缓存加载器只运行一次。它加载元数据了解之前缓存的数据到共享内存区间。在第一次启动后几分钟加载整个缓存立即消耗充足的资源降低Nginx性能。为了避免这个问题,在proxy_cache_path指令上配置迭代加载缓存的参数:

loader_threshold——迭代周期,以毫秒为单位(默认是200)

loader_files——一次加载的项目的最大数量(默认是100)

loader_sleeps——两次迭代之间的延迟,以毫秒为单位(默认是50)

在下面例子中,迭代至少300毫秒或指导200个项目被加载:

proxy_cache_path /data/nginx/cache keys_zone=one:10m loader_threshold=300 loader_files=200;

4 指定那些请求被缓存

默认,Nginx缓存所有第一次请求的HTTP GET和HEAD方法的响应,响应接收自代理服务器。Nginx使用请求字符串作为请求的标识符。如果请求有相同的标识符作为缓存响应,Nginx发送缓存响应到客户端。你能在http、server或location上下文中包括各种指令控制那些响应被缓存。

为了改变用于计算请求的特性,使用proxy_cache_key指令:

proxy_cache_key "$host$request_uri$cookie_user";

为了定义请求使用相同标识符的最小次数后响应被缓存,使用proxy_cache_min_uses指令:

proxy_cache_min_uses 5;

为了缓存GET和HEAD之外的请求的响应,使用proxy_cache_methods指令:

proxy_cache_methods GET HEAD POST;

5 限制或绕过缓存

默认,响应无限期的保存在响应中。只有当超过最大配置大小时,然后才会按从它们上次被请求持续时间的顺序删除。你能设置缓存响应多久失效,甚至是否它们完全使用。

使用proxy_cache_valid指令限制带有特定状态码的响应有效时间:

proxy_cache_valid 200 302 10m;

proxy_cache_valid 404 1m;

在嗓门的例子中,状态码为200或302的响应有效期是10分钟,状态码为404的响应有效期是1分钟。为了定义所有响应的有效期使用any作为第一个参数:

proxy_cache_valid any 5m;

使用proxy_cache_bypass指令定义Nginx不发送响应到客户端的条件。每个参数定义一个条件,由大量变量组成。如果至少一个参数不为空并且不等于“0”,Nginx不在缓存中查找响应,而是立即将请求转发到后端服务器。

proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;

使用proxy_no_cache指令定义Nginx不缓存响应的条件。与proxy_cache_bypass参数相同。

proxy_no_cache $http_pragma $http_authorization;

6 从缓存清除内容

Nginx可以从缓存删除过时的缓存文件。删除过时的缓存内容是有必要的,防止同时服务新老版本的Web页面。缓存请求接收特定“purge”请求要么包含一个自定义HTTP头,要么是“OURGE”HTTP方法。

6.1 配置缓存清理

让我们设置配置使用“PURGE”HTTP方法和检测匹配URLs标识请求。

在http级别,创建新变量,例如,$purge_method,将依赖于$request_method变量:

http {

...

map $request_method $purge_method{

PURGE 1;

default 0;

}

}

在配置缓存的location中,proxy_cache_purge指定缓存purge请求的条件。在我们的例子中,它是上一步配置的$purge_method

server {

listen 80;

server_name www.example.com;

 

location / {

proxy_pass https://localhost:8002;

proxy_cache mycache;

 

proxy_cache_purge $purge_method;

}

}

6.2 发送清理命令

当proxy_cache_purge指令被配置时,你将需要发送一个特定的缓存清理请求清理缓存。你会问清理缓存使用一系列工具,例如,curl命令:

$ curl -X PURGE -D – "https://www.example.com/*"

HTTP/1.1 204 No Content

Server: nginx/1.5.7

Date: Sat, 01 Dec 2015 16:33:04 GMT

Connection: keep-alive

在该例子中,资源有一个公共URL部分(通过星号通配符)将被删除。然而,整个缓存不会完全从缓存中删除:它们将保留在磁盘直到inactivity(proxy_cache_path)或缓存清理进程处理时或客户端尝试访问它们时删除。

6.3 限制清理命令访问

推荐配置允许发送缓存清理请求的IP地址限制:

geo $purge_allowed {

default 0; # deny from other

10.0.0.1 1; # allow from localhost

192.168.0.0/24 1; # allow from 10.0.0.0/24

}

 

map $request_method $purge_method {

PURGE $purge_allowed;

default 0;

}

在该例子中,Nginx检查该请求是否“PURGE”方法,如果是,分析客户端的IP地址。如果IP地址是白名单,那么$purge_method设置为$purge_allowed:1,允许清理,0,拒绝清理。

6.4 完全从缓存中删除文件

完全删除匹配星号的缓存文件,你将需要激活特定缓存清理进程将永久遍历所有缓存条目并删除匹配通配符键的条目。在http级别,添加purger参数给proxy_cache_path指令:

proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=mycache:10mpurger=on;

6.5 缓存清理配置实例

http {

...

proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=mycache:10m purger=on;

 

map $request_method $purge_method {

PURGE 1;

default 0;

}

 

server {

listen 80;

server_name www.example.com;

 

location / {

proxy_pass https://localhost:8002;

proxy_cache mycache;

proxy_cache_purge $purge_method;

}

}

 

geo $purge_allowed {

default 0;

10.0.0.1 1;

192.168.0.0/24 1;

}

 

map $request_method $purge_method {

PURGE $purge_allowed;

default 0;

}

}

7 字节范围缓存

有时,最初的缓存填充操作可能需要一些时间,尤其是大文件。当第一个请求开始下载一个影音文件的一部分时,下一个请求将要等待整个文件下载并放入缓存。

Nginx可以缓存这么一个范围的请求并使用缓存切片模块逐渐填充缓存。文件被切分成更小的“分片”。每个范围请求选择覆盖请求范围的特定分片,如果这个范围没有缓存,放置它到缓存中。所有到这些分片的其它请求将从缓存中获取响应。

为了启用字节范围缓存:

确保你的Nginx编译了slice模块。

使用slice指令指定分片大小:

location / {

slice 1m;

}

分片大小应该调整为足够快的下载分片。太小可能导致浪费过多的内存,并且处理请求时要打开大量的文件描述符,而值太大会导致延迟。

包括$slice_range变量到缓存键中

proxy_cache_key $uri$is_args$args$slice_range;

启用状态码为206的响应的缓存:

proxy_cache_valid 200 206 1h;

启用传入范围请求到代理服务器通过传入$slice_range变量到Range头字段:

proxy_set_header Range $slice_range;

二进制范围缓存例子:

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;

}

注意,如果分片缓存打开,最初的文件不应该改变。

7.1 联合配置示例

http {

...

proxy_cache_path /data/nginx/cache keys_zone=one:10m loader_threshold=300

loader_files=200 max_size=200m;

 

server {

listen 8080;

proxy_cache one;

 

location / {

proxy_pass http://backend1;

}

 

location /some/path {

proxy_pass http://backend2;

proxy_cache_valid any 1m;

proxy_cache_min_uses 3;

proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;

}

}

}

在该例子中,两个location使用相同的缓存,但方式不同。

因为来自backend1服务器的响应很少改变,没有缓存控制指令。第一次响应缓存的请求,并永久保存。

相比之下,来自backend1服务器的响应改变频繁,因此它们的有效期只有1分钟并且直到同样的请求发生三次才会缓存。然而,如果proxy_cache_bypass指令指定请求匹配条件,Nginx立即传递请求给backend2而不去检查缓存。