缓存来自代理的Web和应用程序服务器的静态和动态内容,以加快向客户端的交付速度并减少服务器上的负载。
概述
启用缓存后,NGINX Plus 将响应保存在磁盘缓存中,并使用它们来响应客户端,而不必每次都代理对相同内容的请求。
要了解有关 NGINX Plus 缓存功能的更多信息,请按需观看NGINX内容缓存网络研讨会,并深入了解动态内容缓存 、缓存清除和延迟缓存等功能。
启用响应缓存
要启用缓存,请proxy_cache_path 在*http {}上下文中包含该指令。第一个强制参数是缓存内容的本地文件系统路径,强制keys_zone参数定义用于存储有关缓存项的元数据的共享内存区域的名称和大小:
http {
# ...
proxy_cache_path /data/nginx/cache keys_zone=one:10m;
}
然后proxy_cache 在要缓存服务器响应的上下文(协议类型、虚拟服务器或位置)中包含指令,指定由指令的keys_zone参数定义的区域名称proxy_cache_path(在本例中为one):
http {
# ...
proxy_cache_path /data/nginx/cache keys_zone=one:10m;
server {
proxy_cache mycache;
location / {
proxy_pass http://localhost:8000;
}
}
}
请注意,该keys_zone参数定义的大小不限制缓存响应数据的总量。缓存的响应本身与文件系统上特定文件中的元数据副本一起存储。要限制缓存响应数据的数量,请将max_size参数包含在proxy_cache_path 指令中。(但请注意,缓存数据量可能会暂时超过此限制,如下一节所述。)
涉及缓存的 NGINX 进程
有两个额外的 NGINX 进程参与缓存:
该高速缓存管理器周期性地起动,检查高速缓存的状态。如果缓存大小超过 指令的max_size参数设置的限制proxy_cache_path,缓存管理器将删除最近最少访问的数据。如前所述,在缓存管理器激活之间的时间内,缓存数据量可能会暂时超过限制。
该缓存加载器只运行一次,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;
指定要缓存的请求
默认情况下,NGINX Plus 缓存第一次从代理服务器收到此类响应时,对使用 HTTPGET和HEAD方法发出的请求的所有响应。作为请求的密钥(标识符),NGINX Plus 使用请求字符串。如果请求与缓存响应具有相同的键,NGINX Plus 将缓存响应发送到客户端。您可以在不同的指令http {},server {}或location {}上下文来控制其响应缓存。
要更改用于计算密钥的请求特征,请包含以下proxy_cache_key 指令:
proxy_cache_key "$host$request_uri$cookie_user";
要定义在缓存响应之前必须发出具有相同键的请求的最小次数,请包含proxy_cache_min_uses 指令:
proxy_cache_min_uses 5;
要使用GETand以外的方法缓存对请求的响应HEAD,请将它们与GET和HEAD作为proxy_cache_methods 指令的参数一起列出:
proxy_cache_methods GET HEAD POST;
限制或禁用缓存
默认情况下,响应会无限期地保留在缓存中。仅当缓存超过最大配置大小时才会删除它们,然后按自上次请求以来的时间长度排序。您可以设置多长时间缓存的响应被认为是有效的,甚至他们是否在所有使用,通过在指示http {},server {}或location {}上下文:
要限制具有特定状态代码的缓存响应被视为有效的时间,请包含以下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;
要定义 NGINX Plus 不向客户端发送缓存响应的条件,请包含该proxy_cache_bypass 指令。每个参数定义一个条件并由多个变量组成。如果至少有一个参数不为空且不等于“ 0”(零),NGINX Plus 不会在缓存中查找响应,而是立即将请求转发到后端服务器。
proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;
要定义 NGINX Plus 根本不缓存响应的条件,请包含proxy_no_cache 指令,以与proxy_cache_bypass指令相同的方式定义参数。
proxy_no_cache $http_pragma $http_authorization;
从缓存中清除内容
NGINX 可以从缓存中删除过时的缓存文件。这对于删除过时的缓存内容以防止同时提供新旧版本的网页是必要的。收到包含自定义 HTTP 标头或 HTTPPURGE方法的特殊“清除”请求时,将清除缓存。
配置缓存清除
让我们设置一个配置来识别使用 HTTPPURGE方法的请求并删除匹配的 URL。
在http {}上下文中,创建一个$purge_method取决于变量的新变量,例如$request_method:
http {
# ...
map $request_method $purge_method {
PURGE 1;
default 0;
}
}
在location {}配置缓存的块中,包含proxy_cache_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;
}
}
发送清除命令
当proxy_cache_purge指令配置,你需要发送一个特殊的缓存清除请求清除缓存。您可以使用一系列工具发出清除请求,包括curl本示例中的命令:
$ curl -X PURGE -D – "https://www.example.com/*"
HTTP/1.1 204 No Content
Server: nginx/1.15.0
Date: Sat, 19 May 2018 16:33:04 GMT
Connection: keep-alive
在示例中,具有公共 URL 部分(由星号通配符指定)的资源被清除。但是,此类缓存条目不会完全从缓存中删除:它们保留在磁盘上,直到它们因不活动(由 指令的inactive参数确定proxy_cache_path)或缓存清除器(使用purger 参数 to启用proxy_cache_path)或客户端而被删除尝试访问它们。
限制对清除命令的访问
我们建议您限制允许发送缓存清除请求的 IP 地址数量:
geo $purge_allowed {
default 0; # deny from other
10.0.0.1 1; # allow from 10.0.0.1 address
192.168.0.0/24 1; # allow from 192.168.0.0/24
}
map $request_method $purge_method {
PURGE $purge_allowed;
default 0;
}
在这个例子中,NGINX 检查该PURGE方法是否在请求中使用,如果是,则分析客户端 IP 地址。如果 IP 地址被列入白名单,则$purge_method设置为$purge_allowed:1允许清除,并0拒绝它。
从缓存中完全删除文件
要完全删除与星号匹配的缓存文件,请激活一个特殊cache purger过程,该过程会永久迭代所有缓存条目并删除与通配符键匹配的条目。 在上下文中包含指令的purger 参数:proxy_cache_pathhttp {}
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=mycache:10m purger=on;
缓存清除配置示例
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;
}
}
字节范围缓存
初始缓存填充操作有时需要相当长的时间,尤其是对于大文件。例如,当一个视频文件开始下载以满足部分文件的初始请求时,后续请求必须等待整个文件下载并放入缓存中。
NGINX 可以缓存此类范围请求,并使用Cache Slice 模块逐渐填充缓存,该模块将文件划分为更小的“切片”。每个范围请求选择覆盖所请求范围的特定切片,如果该范围仍未缓存,则将其放入缓存中。对这些切片的所有其他请求都从缓存中获取数据。
要启用字节范围缓存:
确保 NGINX 是使用缓存切片 模块编译的。
使用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;
}
请注意,如果打开切片缓存,则不得更改初始文件。
组合配置示例
以下示例配置结合了上述一些缓存选项。
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 mycache;
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;
}
}
}
在此示例中,两个位置使用相同的缓存,但方式不同。
因为响应backend1很少改变,所以不包含缓存控制指令。响应在第一次发出请求时被缓存,并且无限期地保持有效。
相比之下,对请求服务的响应backend2频繁更改,因此它们仅在 1 分钟内有效,并且在发出 3 次相同请求之前不会被缓存。此外,如果请求与proxy_cache_bypass指令定义的条件匹配,NGINX Plus 会立即将请求传递给 ,backend2而无需在缓存中查找相应的响应。