当前位置: 首页 > news >正文

【NGINX--4】大规模可扩展的内容缓存

1、缓存区

缓存内容并定义缓存的存储位置。

使用 proxy_cache_path 指令定义共享内存缓存区和内容的位置:

proxy_cache_path /var/nginx/cachekeys_zone=CACHE:60m levels=1:2inactive=3h max_size=20g;
proxy_cache CACHE;

上述缓存定义示例在文件系统 /var/nginx/cache 中为缓存响应创建了一个目录,以及一个名为 CACHE、大小为 60M 的共享内存空间。此示例设置了目录结构级别,定义了如果缓存响应在 3 小时内未被请求就被释放,同时定义了最大缓存大小为 20GB。proxy_cache 指令通知特定上下文使用缓存区。proxy_cache_path 在 http 上下文中有效,proxy_cache 指令在 http、server 和 location 上下文中有效。
详解
要在 NGINX 中配置缓存,就必须声明要使用的路径和区域。您可以使用 proxy_cache_path 指令创建 NGINX 中的缓存区。proxy_cache_path 指定了存储缓存信息的位置,以及存储活动键和响应元数据的共享内存空间。该指令的可选参数对维护和访问缓存的方式提供了更多控制。levels 参数定义了文件结构的创建方式。该值用冒号分隔,声明了子目录名称的长度,最多支持三个级别。NGINX 缓存以缓存键(一个哈希值)为基础,它将结果存储在提供的文件结构中,使用缓存键作为文件路径并根据levels 值分解目录。inactive 参数能够控制缓存项在最后一次使用后驻留的时间长度。您也可以使用 max_size 参数配置缓存的大小。其他参数与缓存加载进程有关,这个进
程可以将缓存键从磁盘的缓存文件加载到共享内存

2、缓存锁定

您不希望 NGINX 将当前正在写入缓存的请求代理到上游(upstream)服务器。

使用 proxy_cache_lock 指令确保一次只能将一个请求写入缓存,随后的请求将等待响应被写入:

proxy_cache_lock on; 
proxy_cache_lock_age 10s; 
proxy_cache_lock_timeout 3s;

详解
proxy_cache_lock 指令指示 NGINX 保存当前正在填充的请求,这些请求最终将成为被缓存的元素。根据 proxy_cache_lock_age 指令的定义,代理请求填充缓存的时间是有限制的,默认为 5 秒,此后才允许另一个请求填充元素。NGINX 还允许将已经等待指定时间(同样默认为 5 秒)的请求传递到代理服务器,该请求不会尝试通过使用 proxy_cache_lock_timeout 指令来填充缓存。您可以将 proxy_cache_lock_age 理解成“你花的时间太长了,我来为你填充缓存”,将 proxy_cache_lock_timeout 理解成“你让我等的时间太长了,你先慢慢填充,我去干点别的”。

3、缓存哈希键

控制内容的缓存和检索方式。

使用 proxy_cache_key 指令和变量定义缓存的命中或未命中:

proxy_cache_key "$host$request_uri $cookie_user";

上述缓存哈希键将根据被请求的主机和 URI、定义用户的 cookie 指示 NGINX 缓存页面。这样您就可以缓存动态页面,而且不用提供为其他用户生成的内容。
详解
proxy_cache_key 的默认配置是“ s c h e m e scheme schemeproxy_host$request_uri”,该配置适用于大多数用例。使用的变量包括 scheme、HTTP 或 HTTPS、proxy_host(发送请求)以及请求 URI。总之,这反映了 NGINX 将请求代理到哪个 URL。您可能会发现,还有许多其他因素定义了每个应用的唯一请求,比如请求参数、请求头、会话标识符等等,您希望为这些因素创建自己的哈希键。

NGINX 提供了这些变量的列表

选择一个好的哈希键非常重要,其中离不开对应用的了解。为静态内容选择缓存键通常非常简单,只需使用主机名和 URI 便可。但如果是为相当动态的内容(例如仪表盘应用的页面)选择缓存键,就要求对用户与应用的交互方式以及用户体验之间的差异程度有着更深刻的认识。出于安全考虑,您可能不希望在没有完全了解上下文的情况下就将用户的缓存数据展示给其他用户。proxy_cache_key 指令将字符串配置为缓存键的哈希值,该指令可以在 http、server 和 location 代码块中进行设置,从而灵活控制请求的缓存方式。

4、绕过缓存

绕过缓存。

使用具有非空或非零值的 proxy_cache_bypass 指令。动态执行此操作的一种方法是,在您不希望进行缓存的 location 代码块内,使用一组字符串不能为空或为 0 的变量:

proxy_cache_bypass $http_cache_bypass;

该配置指示 NGINX,如果名为 cache_bypass 的 HTTP 请求头的值不是 0,则绕过缓存。本例使用请求头作为变量来确定是否应该绕过缓存 —— 客户端需要专门为其请求设置此请求头。
详解
我们有很多使用场景都不要求缓存请求。为此,NGINX 提供了 proxy_cache_bypass 指令。这样,当值设置为非空或非零时,请求将被发送到上游(upstream)服务器,而不是从缓存中拉取。绕过缓存的不同需求和场景将由您的应用的用例来决定。绕过缓存可以简单到只需使用请求头或响应头就能搞定,也会复杂到协同配合多个 map 代码块来解决。

绕过缓存的原因有很多,比如为了故障排除或调试。如果您总是拉取缓存的页面,或者您的缓存键只是针对一个用户标识符的,那么复盘问题可能会很难。因此,具备绕过缓存的能力十分重要。绕过缓存的方法有很多,包括但不限于设置特定的 cookie、请求头或请求参数时等。您还可以通过设置 proxy_cache off;,彻底关闭给定上下文(例如 location 代码块)的缓存功能。

5、缓存性能

通过在客户端缓存内容来提高性能。

使用客户端的 cache-control HTTP 请求头:

location ~* \.(css|js)$ { expires 1y;add_header Cache-Control "public";
}

这个 location 代码块指定客户端可以缓存 CSS 和 JavaScript 文件的内容。expires 指令指示客户端将缓存资源的有效期设置为一年。add_header 指令将 HTTP 响应头Cache-Control 添加到响应中,值为 public,允许沿途的所有缓存服务器缓存资源。如果将值设置为 private,则只允许客户端缓存资源。
详解
缓存性能有许多影响因素,其中磁盘速度最为重要。NGINX 配置中有很多指令可以帮助提升缓存性能。其中一种方法是设置 HTTP 响应头,让客户端只缓存响应但是不向NGINX 发送请求,这样只需读取缓存便可。

6、NGINX Plus 之缓存清除

使缓存中的对象变得无效。

使用 proxy_cache_purge 指令(NGINX Plus 的清除功能)以及非空或零值变量:

map $request_method $purge_method { PURGE 1;default 0;
}
server {# ...location / {# ...proxy_cache_purge $purge_method;}
}

在此示例中,如果使用 PURGE 方法请求特定对象,那么它的缓存将被清除。以下是使用 curl 清除名为 main.js 的文件缓存的示例:

$ curl -XPURGE localhost/main.js

详解
处理静态文件的一种常见方法是将文件的哈希放在文件名中。当您推出新的代码和内容时,这可以确保您的 CDN 将其识别为新文件(因为 URI 已更改)。但是,对设置了不适合此模型的缓存键的动态内容来说,这种方法并不好用。在每种缓存场景中,您都必须有一种对应的清除缓存的方法。NGINX Plus 的处理方法很简单,只要将 proxy_cache_purge 指令的值设置为非零或非空,与请求匹配的缓存项就被会清除掉。此外还有一种简便方法,那就是为 PURGE 映射请求方法。但是您可能需要配合使用 geo_ip 模块或简单的身份验证方法,以确保不是任何人都能清除您宝贵的缓存项。NGINX 还允许使用 * 来清除与常见 URI 前缀相匹配的缓存项。要使用通配符,您需要使用
purger=on 参数配置 proxy_cache_path 指令。

7、缓存切片

需要通过将文件分段来提高缓存效率。

使用 NGINX slice 指令及其嵌入式变量将缓存结果分段:

proxy_cache_path /tmp/mycache keys_zone=mycache:10m; 
server {# ...proxy_cache mycache;slice 1m;proxy_cache_key $host$uri$is_args$args$slice_range;proxy_set_header Range $slice_range; proxy_http_version 1.1;proxy_cache_valid 200 206 1h;location / {proxy_pass http://origin:80;}
}

详解
此配置为服务器定义并启用了一个缓存区。slice 指令指示 NGINX 将响应分成 1MB 的文件段。缓存文件根据 proxy_cache_key 指令进行存储。请注意,该指令使用了一个名为 slice_range 的嵌入式变量。向源端发送请求时也使用了同一变量作为请求头,并且该请求的 HTTP 版本已升级到 HTTP/1.1,因为 1.0 不支持字节范围的请求。200 或206 响应码的缓存有效期设为 1 个小时,然后定义位置和源端。

Cache Slice 模块是为了交付 HTML5 视频开发的,它使用字节范围的请求将伪流内容传输到浏览器。默认情况下,NGINX 能够从缓存中提供字节范围的请求。如果对未缓存的内容发出了一个字节范围的请求,NGINX 将向源端请求整个文件。当您使用Cache Slice 模块时,NGINX 仅向源端请求必要的文件段。如果请求范围大于切片大小(包括整个文件),就会触发对每个所需文件段的子请求,并对这些文件段进行缓存处理。当所有文件段都被缓存后,系统将组合响应并将它们发送给客户端,这使得NGINX 能够更有效地缓存并提供请求的范围内的内容。

Cache Slice 模块只能用于不会进行更改的大文件。NGINX 每接收一个来自源端的文件段,就验证一次 ETag。如果源端的 ETag 发生了变化,那么由于缓存不再有效,NGINX 就会中止这个段的缓存填充。如果内容确实发生了变化,文件也变小了,或者如果源端可以处理缓存填充过程中的负载峰值,那么最好使用下面“其他参考资料”所列博客中描述的 Cache Lock 模块。默认情况下不创建该模块,您需要在构建 NGINX 时使用 --with-http_slice_module 配置来启用。

参考资料
“使用 NGINX 和 NGINX Plus 智能高效地进行字节范围的缓存”

相关文章:

  • STC单片机选择外部晶振烧录程序无法切换回内部晶振导致单片机不能使用
  • 帝国cms开发一个泛知识类的小程序的历程记录
  • CNVD-2023-12632:泛微E-cology9 browserjsp SQL注入漏洞复现 [附POC]
  • 『亚马逊云科技产品测评』活动征文|通过Lightsail搭建个人笔记
  • 《安富莱嵌入式周报》第327期:Cortex-A7所有外设单片机玩法LL/HAL库全面上线,分享三款GUI, PX5 RTOS推出网络协议栈,小米Vela开源
  • ④【Set】Redis常用数据类型: Set [使用手册]
  • 电子学会C/C++编程等级考试2022年12月(一级)真题解析
  • Linux安装Mysql详细教程(两种安装方法)
  • PyTorch中并行训练的几种方式
  • k8s安装jenkins
  • SpringCloud微服务 【实用篇】| Eureka注册中心、Ribbon负载均衡
  • 如何开发干洗店用的小程序
  • ChatGPT 也并非万能,品牌如何搭上 AIGC「快班车」
  • 代码规范之-理解ESLint、Prettier、EditorConfig
  • 【Nginx】nginx 解决504超时问题
  • 4月23日世界读书日 网络营销论坛推荐《正在爆发的营销革命》
  • C学习-枚举(九)
  • gitlab-ci配置详解(一)
  • hadoop集群管理系统搭建规划说明
  • js中的正则表达式入门
  • spring + angular 实现导出excel
  • spring-boot List转Page
  • Spring-boot 启动时碰到的错误
  • 等保2.0 | 几维安全发布等保检测、等保加固专版 加速企业等保合规
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 使用 Node.js 的 nodemailer 模块发送邮件(支持 QQ、163 等、支持附件)
  • 使用docker-compose进行多节点部署
  • 算法之不定期更新(一)(2018-04-12)
  • 译自由幺半群
  • 源码之下无秘密 ── 做最好的 Netty 源码分析教程
  • 新年再起“裁员潮”,“钢铁侠”马斯克要一举裁掉SpaceX 600余名员工 ...
  • ​2021半年盘点,不想你错过的重磅新书
  • #绘制圆心_R语言——绘制一个诚意满满的圆 祝你2021圆圆满满
  • ()、[]、{}、(())、[[]]命令替换
  • (ISPRS,2023)深度语义-视觉对齐用于zero-shot遥感图像场景分类
  • (Python第六天)文件处理
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)讲解
  • (zt)最盛行的警世狂言(爆笑)
  • (二)JAVA使用POI操作excel
  • (三)mysql_MYSQL(三)
  • (实战)静默dbca安装创建数据库 --参数说明+举例
  • (四)搭建容器云管理平台笔记—安装ETCD(不使用证书)
  • (淘宝无限适配)手机端rem布局详解(转载非原创)
  • (原創) 如何讓IE7按第二次Ctrl + Tab時,回到原來的索引標籤? (Web) (IE) (OS) (Windows)...
  • .Net 8.0 新的变化
  • .netcore 如何获取系统中所有session_ASP.NET Core如何解决分布式Session一致性问题
  • .NET企业级应用架构设计系列之应用服务器
  • .NET设计模式(7):创建型模式专题总结(Creational Pattern)
  • /boot 内存空间不够
  • @Documented注解的作用
  • @test注解_Spring 自定义注解你了解过吗?
  • [2]十道算法题【Java实现】
  • [2016.7 day.5] T2
  • [AIGC] 使用Curl进行网络请求的常见用法