缓存功能

1. 功能描述

NJET会缓存来自代理 Web 或应用程序服务器的静态和动态内容,以加快向客户端的响应速度并减少上游服务器上的负载。启用缓存后,NjET将响应保存在NjET磁盘缓存中,并使用它们来响应客户端,而不必每次都对相同内容向上游服务器发起请请求。

2.使用介绍

2.1启用缓存

若要启用缓存,请在Http上下文中包含 proxy_cache_path指令。第一个参数是缓存内容的本地文件系统路径,第二个参数定义用于存储有关缓存项的元数据的共享内存区域的名称和大小。

http {
    # ...
    proxy_cache_path /data/njet/cache keys_zone=mycache:10m;
}

然后在要缓存server响应的上下文(http、server或location)中包含proxy_cache指令,并指定由上述指令参数定义的共享内存区域名称。

http {
    # ...
    proxy_cache_path /data/njet/cache keys_zone=mycache:10m;
    server {
        proxy_cache mycache;
        location / {
            proxy_pass http://localhost:8000;
        }
    }
}

请注意,参数定义的大小不会限制缓存响应数据的总量。缓存的响应本身与元数据的副本一起存储在文件系统上的特定文件中。要限制缓存的响应数据量,请将参数max_size 配置在 proxy_cache_path指令中。(但请注意,缓存的数据量可能会暂时超过此限制)。

2.2指定要缓存的请求

默认情况下,NJET会在第一次从代理服务器收到此类响应时缓存对使用HTTP GET和HEAD方法发出的请求的所有响应。NJET使用请求字符串作为请求的标识符。如果请求与缓存的响应具有相同的键,NJET会将缓存的响应发送到客户端。您可以在 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;

2.3 限制或禁用缓存

默认情况下,响应无限期地保留在缓存中。仅当缓存超过最大配置大小时,才会删除它们,然后按自上次请求它们以来的时间排序最长最少使用的缓存进行删除。您可以通过在http{} 、server{} 或location{}上下文中包含指令来设置缓存响应被视为有效的时间和是否使用缓存:

要限制具有特定状态代码的缓存响应被视为有效的时间,请使用 proxy_cache_valid 指令:

proxy_cache_valid 200 302 10m;
proxy_cache_valid 404      1m;

在此示例中,包含代码200或302的响应被视为有效 10 分钟,包含代码的响应的有效期为 1 分钟。要定义具有所有状态代码的响应的有效期,请指定为第一个参数为any:

proxy_cache_valid any 5m;

要定义NjET不向客户端发送缓存响应的条件,请使用proxy_cache_bpass指令。每个参数定义一个条件,并由许多变量组成。如果至少有一个参数不为空且不等于"0",NJET不会在缓存中查找响应,而是立即将请求转发到后端服务器。

注意:

关于缓存清理还有一个很重要的参数需要配置

proxy_cache_path 后面的inactive参数,该参数表示资源不活跃时间,在该时间内如果资源没有被访问,也会被清理掉,尽管proxy_cache_valid 后面设置的有效期还没到,该资源也会被删除掉

补充:(后面可以跟很多字符串(可以为变量),只要有一个字符串不为空并且不等于"0", 则都会走pass, 所以bypass数字都会加1.)

proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;

要定义NJET根本不缓存响应的条件,请使用proxy_no_cache指令,并以与proxy_cache_bypass指令相同的方式定义参数。( 如果字符串参数中至少有一个值不为空且不等于“0”,则不会保存响应)

proxy_no_cache $http_pragma $http_authorization;

2.4 从缓存中清除内容

NjET可以从缓存中删除过时的缓存文件。这对于删除过时的缓存内容以防止同时提供旧版和新版本的网页是必需的。缓存在收到包含自定义 HTTP 标头或 HTTP 方法的特殊“PURGE”请求时被清除。

2.4.1 配置缓存清除功能

让我们设置一个配置来标识使用 HTTP PURGE 方法的请求并删除匹配的 URL。

在上下文中,使用map创建一个新变量,例如:

http {# ...
    map $request_method $purge_method {
        PURGE 1;
        default 0;
    }
}

在配置缓存的location{}块中,配置proxy_cache_purge 指令以指定缓存清除请求的条件。在我们的示例中,它是在上一步中配置的:

server {
    listen      80;
    server_name www.example.com;
    location / {
        proxy_pass  https://localhost:8002;
        proxy_cache mycache;
        proxy_cache_purge $purge_method;
    }
}

2.4.2 发送PURGE请求

配置proxy_cache_purge指令后,需要发送特殊的缓存清除请求来清除缓存。您可以使用一系列工具发出清除请求,包括以下示例中的curl命令:

$ curl -X PURGE -D – "https://www.example.com/*"
HTTP/1.1 204 No Content
Server: njet/1.23.2
Date: Sat, 19 May 2018 16:33:04 GMT
Connection: keep-alive

在此示例中,将清除具有公共 URL 部分(由星号通配符指定)的资源。但是,此类缓存条目不会立即从缓存中完全删除:它们将保留在磁盘上,直到它们因不活动(由 proxy_cache_path 指令的参数确定)或缓存清除器(使用 purge 参数启用)而被删除,或者客户端尝试访问它们。

2.4.3 限制对清除命令的访问

我们建议您限制允许发送缓存清除请求的 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;
}

在此示例中,NjET 检查请求中是否使用了PURGE方法,如果是则分析客户端 IP 地址。如果 IP 地址已列入白名单,则 设置为 : 允许清除,否则拒绝清除。

2.4.4 从缓存中完全删除文件

要完全删除与星号匹配的缓存文件,请激活purge功能,该功能将循环访问所有缓存条目并删除与通配符键匹配的条目。在配置中包含 purge 参数到proxy_cache_path指令:

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

缓存清除配置示例

http {# ...
    proxy_cache_path /data/njet/cache levels=1:2 keys_zone=mycache:10m purger=on;
    
    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;
    }
}

2.5 文件分片缓存

初始缓存填充操作有时需要相当长的时间,尤其是对于大文件。例如,当视频文件开始下载以满足对文件一部分的初始请求时,后续请求必须等待整个文件下载并放入缓存中。

NJET可以缓存此类分片请求,并使用缓存切片模块逐渐填充缓存,该模块将文件划分为较小的“分片”。每个Range请求都会选择覆盖所请求范围的特定切片,如果此Range仍未缓存,则将其放入缓存中。对这些切片的所有其他请求都会从缓存中获取数据。

2.5.1 开启分片缓存

使用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;
}

2.6 组合配置示例

以下示例配置结合了上述一些缓存选项。

http {
    # ...
    proxy_cache_path /data/njet/cache keys_zone=mycache:10m loader_threshold=300loader_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;
        }
    }
}

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

由于backend1响应很少更改,因此不包括缓存控制指令。响应在首次发出请求时缓存,并无限期有效。

相比之下,对backend2请求的响应经常更改,因此它们被认为仅在 1 分钟内有效,并且在发出 3 次相同的请求之前不会缓存。此外,如果请求符合proxy_cache_bypass指令定义的条件,NjET会立即将请求传递给backend2,而无需在缓存中查找相应的响应。