Nginx R31 doc-07-内容缓存

NGINX 内容缓存

从代理的 Web 和应用服务器缓存静态和动态内容,以加快向客户端的传输速度并减轻服务器的负载。

概览

启用缓存时,NGINX Plus 会将响应保存在磁盘缓存中,并使用它们来响应客户端,而无需每次都代理相同内容的请求。

要了解有关 NGINX Plus 缓存功能的更多信息,请观看点播的 Content Caching with NGINX 网络研讨会,并深入了解诸如动态内容缓存、缓存清除和延迟缓存等功能。

启用响应缓存

要启用缓存,请在顶级 http {} 上下文中包含 proxy_cache_path 指令。第一个必需参数是用于缓存内容的本地文件系统路径,必需的 keys_zone 参数定义了用于存储关于缓存项的元数据的共享内存区的名称和大小:

nginx 复制代码
http {
    # ...
    proxy_cache_path /data/nginx/cache keys_zone=mycache:10m;
}

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

nginx 复制代码
http {
    # ...
    proxy_cache_path /data/nginx/cache keys_zone=mycache:10m;
    server {
        proxy_cache mycache;
        location / {
            proxy_pass http://localhost:8000;
        }
    }
}

请注意,由 keys_zone 参数定义的大小不限制缓存响应数据的总量。缓存的响应本身存储在文件系统上的特定文件中,其中包含元数据的副本。要限制缓存响应数据的总量,请在 proxy_cache_path 指令中包含 max_size 参数。(但请注意,缓存数据的量在缓存管理器激活之间的时间段内可能会暂时超过此限制,如下一节所述。)

参与缓存的 NGINX 进程

在缓存中涉及两个额外的 NGINX 进程:

  • 缓存管理器定期激活以检查缓存的状态。如果缓存大小超过由 proxy_cache_path 指令中的 max_size 参数设置的限制,缓存管理器将删除最近最少访问的数据。如前所述,缓存数据的量在缓存管理器激活之间的时间段内可能会暂时超过此限制。

  • 缓存加载器仅在 NGINX 启动后立即运行一次。它将先前缓存数据的元数据加载到共享内存区中。一次性加载整个缓存可能会消耗足够的资源,从而在启动后的前几分钟内降低 NGINX 的性能。为了避免这种情况,请通过在 proxy_cache_path 指令中包含以下参数来配置缓存的迭代加载:

    • loader_threshold -- 迭代的持续时间,以毫秒为单位(默认值为 200)
    • loader_files -- 在一次迭代中加载的最大项目数(默认值为 100)
    • loader_sleeps -- 迭代之间的延迟,以毫秒为单位(默认值为 50)

在以下示例中,迭代持续时间为 300 毫秒,或者在加载 200 个项目后停止:

nginx 复制代码
proxy_cache_path /data/nginx/cache keys_zone=mycache:10m loader_threshold=300 loader_files=200;

指定要缓存的请求

默认情况下,NGINX Plus 会缓存所有使用 HTTP GET 和 HEAD 方法发出的请求的响应,第一次收到此类响应时。作为请求的键(标识符),NGINX Plus 使用请求字符串。如果请求具有与缓存响应相同的键,NGINX Plus 将缓存响应发送给客户端。您可以在 http {}、server {} 或 location {} 上下文中包含各种指令,以控制哪些响应被缓存。

要更改用于计算键的请求特征,请包含 proxy_cache_key 指令:

nginx 复制代码
proxy_cache_key "$host$request_uri$cookie_user";

要定义具有相同键的请求必须被制作多少次才能将响应缓存,请包含 proxy_cache_min_uses 指令:

nginx 复制代码
proxy_cache_min_uses 5;

要缓存除 GET 和 HEAD 外的其他方法的请求的响应,请将它们与 GET 和 HEAD 一起列在 proxy_cache_methods 指令的参数中:

nginx 复制代码
proxy_cache_methods GET HEAD POST;

限制或禁用缓存

默认情况下,响应将无限期地保留在缓存中。只有当缓存超过最大配置大小时,它们才会被删除,并且根据它们自上次请求以来的时间长度的顺序进行删除。

您可以通过在 http {}、server {} 或 location {} 上下文中包含指令来设置缓存响应的有效期限,或者甚至确定它们是否被使用:

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

nginx 复制代码
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404      1m;

在此示例中,代码为 200 或 302 的响应在 10 分钟内视为有效,而代码为 404 的响应在 1 分钟内视为有效。要为所有状态代码的响应定义有效时间,请将任何指定为第

一个参数:

nginx 复制代码
proxy_cache_valid any 5m;

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

nginx 复制代码
proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;

要定义 NGINX Plus 在何种情况下根本不缓存响应,请包含 proxy_no_cache 指令,并以与 proxy_cache_bypass 指令相同的方式定义参数。

nginx 复制代码
proxy_no_cache $http_pragma $http_authorization;

清除缓存内容

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

配置缓存清除

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

在 http {} 上下文中,创建一个新变量,例如 $purge_method,它依赖于 $request_method 变量:

nginx 复制代码
http {
    # ...
    map $request_method $purge_method {
        PURGE 1;
        default 0;
    }
}

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

nginx 复制代码
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 命令:

bash 复制代码
$ 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 部分(由星号通配符指定)的资源将被清除。但是,这样的缓存条目并没有完全从缓存中删除:它们仍然保存在磁盘上,直到它们由于不活动(由 proxy_cache_path 指令的 inactive 参数确定)或由缓存清除器(通过 proxy_cache_path 的 purger 参数启用)而被删除,或者客户端尝试访问它们。

限制对清除命令的访问

我们建议您限制允许发送缓存清除请求的 IP 地址数量:

nginx 复制代码
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 表示拒绝。

完全从缓存中删除文件

要完全删除与通配符匹配的缓存文件,激活一个特殊的缓存清除器进程,它会循环遍历所有缓存条目并删除与通配符键匹配的条目。在 http {} 上下文中包含 purger 参数到 proxy_cache_path 指令:

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

字节范围缓存

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

NGINX 使得可以缓存这种范围请求,并逐渐填充缓存,使用 Cache Slice 模块,该模块将文件分成较小的"切片"。每个范围请求选择覆盖请求范围的特定切片,如果该范围仍未缓存,则将其放入缓存中。对于这些切片的所有其他请求从缓存中获取数据。

要启用字节范围缓存:

  • 确保 NGINX 已编译 Cache Slice 模块。
  • 使用 slice 指令指定切片的大小:
nginx 复制代码
location / {
    slice  1m;
}
  • 将 $slice_range 变量包含到缓存键中:
nginx 复制代码
proxy_cache_key $uri$is_args$args$slice_range;
  • 启用响应状态码为 206 的响应的缓存:
nginx 复制代码
proxy_cache_valid 200 206 1h;
  • 通过设置 $slice_range 变量到 Range 头字段,启用将范围请求传递到代理服务器:
nginx 复制代码
proxy_set_header  Range $slice_range;

以下是完整的配置:

nginx 复制代码
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;
}

请注意,如果打开了切片缓存,则初始文件不能更改。

组合配置示例

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

nginx 复制代码
http {
    # ...
    proxy_cache_path /data/nginx/cache keys_zone=mycache

: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,而不会在缓存中查找相应的响应。

nginx 系列

Nginx-01-聊一聊 nginx

Nginx-01-Nginx 是什么

Nginx-02-为什么使用 Nginx

Nginx-02-Nginx Ubuntu 安装 + windows10 + WSL ubuntu 安装 nginx 实战笔记

Nginx-02-基本使用

Nginx-03-Nginx 项目架构

Nginx-04-Docker Nginx

Nginx-05-nginx 反向代理是什么?windows 下如何配置使用 nginx

Nginx-06-nginx 汇总入门介绍

Nginx R31 doc 官方文档-01-nginx 如何安装

Nginx R31 doc-02-nginx 基本功能

Nginx R31 doc-03-HTTP Load Balancing HTTP 负载均衡

Nginx R31 doc-04-HTTP Health Checks

Nginx R31 doc-05-Dynamic Configuration of Upstreams with the NGINX Plus API 使用 NGINX Plus API 动态配置上游服务器

Nginx R31 doc-06-Accepting the PROXY Protocol

Nginx R31 doc-07-内容缓存

Nginx R31 doc-08-Configuring NGINX and NGINX Plus as a Web Server 配置 NGINX 和 NGINX Plus 作为 Web 服务器

Nginx R31 doc-09-Serving Static Content 静态内容

Nginx R31 doc-10-NGINX Reverse Proxy 反向代理

Nginx R31 doc-11-Compression and Decompression 压缩与解压缩

Nginx R31 doc-12-NGINX SSL Termination 安全加密

Nginx R31 doc-13-Limiting Access to Proxied HTTP Resources 访问限流

Nginx R31 doc-14-Dynamic Denylisting of IP Addresses 动态拒绝IP地址

Nginx R31 doc-15-Live Activity Monitoring 实时活动监控

Nginx R31 doc-16-logging 配置日志

Nginx R31 doc-17-debugging 调试

Nginx R31 doc-18-High Availability Support for NGINX Plus in On-Premises Deployments

Nginx 实战-01-nginx ubuntu 安装笔记

Nginx 实战-01-nginx windows 安装笔记

Nginx 实战-02-nginx proxy_pass 服务代理访问 使用笔记 ubuntu nodejs

Nginx 实战-03-nginx 负载均衡

Nginx 实战-04-nginx 不同的地址访问不同的服务

Nginx 实战-05-nginx 反向代理实现域名到指定的 ip

相关推荐
Yaml441 分钟前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~42 分钟前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong16168844 分钟前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端
aloha_7891 小时前
从零记录搭建一个干净的mybatis环境
java·笔记·spring·spring cloud·maven·mybatis·springboot
记录成长java2 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
睡觉谁叫~~~2 小时前
一文解秘Rust如何与Java互操作
java·开发语言·后端·rust
程序媛小果2 小时前
基于java+SpringBoot+Vue的旅游管理系统设计与实现
java·vue.js·spring boot
小屁孩大帅-杨一凡3 小时前
java后端请求想接收多个对象入参的数据
java·开发语言
java1234_小锋3 小时前
使用 RabbitMQ 有什么好处?
java·开发语言
TangKenny3 小时前
计算网络信号
java·算法·华为