Nginx系列13:nginx缓存机制与应用

本节介绍如何启用和配置从代理服务器接收的响应的缓存。主要涉及以下内容 :

  • 缓存介绍
  • 启用响应缓存
  • 涉及缓存的NGINX进程
  • 指定要缓存的请求
  • 限制或绕过缓存
  • 从缓存中清除内容
    • 配置缓存清除
    • 发送清除命令
    • 限制访问清除命令
    • 从缓存中完全删除文件
    • 缓存清除配置示例
  • 字节缓存
  • 组合配置示例

1. 介绍

当启用缓存时,NGINX将响应保存在磁盘缓存中,并使用它们来响应客户端,而不必每次都为同一内容代理请求。

2. 启用响应缓存

要启用缓存,请在顶层的http上下文中包含proxy_cache_path指令。

  • 第一个参数path是缓存内容的本地文件系统路径;
  • levels设置在相对与path指定目录的第几级hash目录中存放缓存数据,通常用1:2设置成两级目录;
  • keys_zoneNginx服务器的缓存索引重建进程在内存中为缓存数据建立索引,后面跟着一对变量用来设置‘存放缓存索引的内存区域的名称和大小’;
  • inactive设置强制更新缓存数据的时间:当缓存在磁盘的数据在指定时间内没有被访问时,nginx就会强制从磁盘上将其删除;
  • max_size磁盘中缓存数据的大小限制,当磁盘中缓存的数据超过最大限制时,缓存管理进程将根据最少被访问的策略删除缓存数据;
http {
    ...
    proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=one:10m inactive=60m max_size=10g;
}

然后在要缓存服务器响应的上下文(协议类型,虚拟服务器或位置)中包含proxy_cache指令,将由keys_zone参数定义的区域名称指定为proxy_cache_path指令(在本例中为一):

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

    server {
        proxy_cache one;
        location / {
            proxy_pass http://localhost:8000;
        }
    }
}

请注意,由keys_zone参数定义的大小不会限制缓存的响应数据的总量。 缓存响应本身存储在文件系统上的特定文件中的元数据副本。 要限制缓存的响应数据量,请将max_size参数包含到proxy_cache_path指令中(但请注意,缓存数据的数量可能会临时超出此限制,如以下部分所述。)

3. 涉及缓存的NGINX进程

缓存中还有两个额外的NGINX进程:

  • 缓存管理器周期性地被激活以检查缓存的状态。 如果缓存大小超过了由max_cize_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 GETHEAD方法的请求的所有响应。 作为请求的密钥(标识符),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之外的方法来缓存对请求的响应,请将它们与GET和HEAD一起列为proxy_cache_methods伪指令的参数:

proxy_cache_methods GET HEAD POST;

5. 限制或绕过缓存

默认情况下,响应将无限期地保留在缓存中。 只有缓存超过最大配置大小,然后按照最后一次请求的时间长度,它们才被删除。 您可以通过在http, server, 或 location上下文中包含指令来设置缓存响应被认为有效的时间长度,甚至是否使用它们。

要限制缓存响应与特定状态代码被认为有效的时间,请包括proxy_cache_valid指令:

proxy_cache_valid 200 302 10m;
proxy_cache_valid 404      1m;

在此示例中,使用代码200302的响应有效时间为10分钟,并且代码404的响应有效1分钟。 要定义具有所有状态代码的响应的有效时间,请指定any作为第一个参数:

proxy_cache_valid any 5m;

要定义NGINX不会向客户端发送缓存响应的条件,请包括proxy_cache_bypass指令。 每个参数定义一个条件并由多个变量组成。 如果至少有一个参数不为空,并且不等于“0”(零),则NGINX不会在缓存中查找响应,而是将请求立即转发到后端服务器。

proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;

要定义NGINX根本不缓存响应的条件,请包括proxy_no_cache指令:

#如果url中匹配到以下正则规则,将cookie_nocache置为1
if ($request_uri ~ ^/(login|register|password\/reset)){
    set $cookie_nocache 1;
}

location / {
   ...
   #对于某些特殊页面关闭nginx缓存
   proxy_no_cache     $cookie_nocache $arg_nocache;
}
...

6. 从缓存中清除内容

NGINX可以从缓存中删除过期的缓存文件。删除过期的缓存内容以防止同时提供旧版本和新版本的网页。 在接收到包含自定义HTTP头或“PURGE” HTTP方法的特殊“purge”请求时,缓存被清除。

6.1 配置缓存清除

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

  1. http块层级上,创建一个新变量,例如:$purge_method,这将取决于$request_method变量:
http {
    ...
    map $request_method $purge_method {
        PURGE 1;
        default 0;
    }
}

  1. location中配置高速缓存,包括指定缓存清除请求的条件的proxy_cache_purge指令。 在我们的例子中,它是在上一步配置的$purge_method

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

    6.3 发送清除命令

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

$ curl -X PURGE -D – "http://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部分(由星号通配符指定)的资源将被删除。 但是,这些高速缓存条目将不会从缓存中完全删除:它们将保留在磁盘上,直到它们被删除为非活动状态(proxy_cache_path的非活动参数),或由缓存清除程序进程处理,或客户端尝试访问它们 。

6.4 限制访问清除命令

建议您配置允许发送缓存清除请求的有限数量的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.5 从缓存中完全删除文件

要完全删除与星号相匹配的缓存文件,您将需要激活一个特殊的缓存清除程序,该过程将永久地遍历所有缓存条目,并删除与通配符相匹配的条目。 在http块级别上,将purger参数添加到proxy_cache_path指令中:

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

6.6 缓存清除配置示例

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        http://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使缓存这样的范围请求成为可能,并逐渐用缓存片模块填充高速缓存。 该文件分为较小的“切片”。 每个范围请求选择将覆盖所请求范围的特定切片,并且如果此范围仍未缓存,请将其放入缓存中。 对这些切片的所有其他请求将从缓存中获取响应。

要启用字节范围缓存:

  1. 确保您的NGINX是使用slice模块编译的。

  2. 使用slice指令指定切片的大小:

    location / {
     slice  1m;
    }
    
    

    slice的大小应适当调整,使切片快速下载。 在处理请求时,太小的大小可能会导致内存使用量过多和大量打开的文件描述符,太大的值可能会导致延迟。

  3. $slice_range变量包含到缓存键中:

proxy_cache_key $uri$is_args$args$slice_range;

  1. 启用使用206状态代码缓存响应:

    proxy_cache_valid 200 206 1h;
    
    
  2. 通过在Range头字段中传递$slice_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;
}

请注意,如果切片(slice)缓存打开,则不应更改初始文件。

8. 组合配置示例

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

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

在这个例子中,两个位置使用相同的缓存,但是以不同的方式。

由于backend1服务器的响应很少更改,因此不包括缓存控制指令。 首次请求响应缓存,并无限期保持有效。

相比之下,对backend2服务的请求的响应频繁变化,因此它们被认为只有1分钟有效,并且在相同请求3次之前不被缓存。 此外,如果请求符合proxy_cache_bypass指令定义的条件,则NGINX会立即将请求传递给backend2,而不在缓存中查找。

原文出自【易百教程】,商业转载请联系作者获得授权,非商业转载请保留原文链接:https://www.yiibai.com/nginx/content-caching.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355

推荐阅读更多精彩内容