前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Nginx缓存原理及机制

Nginx缓存原理及机制

作者头像
创译科技
发布于 2019-09-06 02:12:45
发布于 2019-09-06 02:12:45
1K00
代码可运行
举报
文章被收录于专栏:Node开发Node开发
运行总次数:0
代码可运行

上篇文章介绍了Nginx一个较为重要的知识点:Nginx实现接口限流。本篇文章将介绍Nginx另一个重要知识点:Nginx缓存原理。其实说到缓存技术大家应该都不会很陌生,缓存技术的基本思想其实是对用户已经访问过的内容在Nginx建立副本,如果在一段时间内(缓存尚未过期)再次访问该数据,则不需要重新发起请求获取数据,可以直接从缓存中读取到该数据,好处在于减少了Nginx与后端服务之间的网络交互,减轻了网络的压力,而且在减少数据传输的延迟时同时可以提升用户访问速度。而且如果碰上后端服务出现异常时,还可以通过缓存进行相应用户请求,提高了后端服务的稳定性。

什么是Nginx缓存?

Nginx基于Proxy Store实现,使用Nginxhttp_proxy模块可以实现类似于squid的缓存功能。当启用缓存时,Nginx会将相应数据保存在磁盘缓存中,只要缓存数据尚未过期,就会使用缓存数据来响应客户端的请求。

如何启用缓存?

Nginx启用缓存需要在最顶层的http节点下配置proxy_cache_path命令。我们先看看proxy_cache_path命令的语法结构:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
proxy_cache_path /data/cache keys_zone=niyueling:10m;

可以看到proxy_cache_path命令一共包含两个参数,第一个参数指定缓存保存的本地路径,第二个参数定义缓存数据的共享内存区域的名称和内存区大小。Nginx启动后,缓存加载程序只进行加载一次,加载时会将缓存的元数据加载到共享内存区域,但是如果一次加载整个缓存全部内容可能会使Nginx刚启动的前几分钟性能消耗严重,大幅度降低Nginx的性能。所以可以在proxy_cache_path命令中配置缓存迭代加载。缓存迭代加载一共可以设置三个参数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
loader_threshold - 迭代的持续时间,以毫秒为单位(默认为200)
loader_files     - 在一次迭代期间加载的最大项目数(默认为100)
loader_sleeps    - 迭代之间的延迟(以毫秒为单位)(默认为50)

我们可以看下一个小例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
proxy_cache_path /data/cache keys_zone=niyueling:10m loader_threshold=300 loader_files=200;

在这个例子中缓存迭代加载可以持续300毫秒或者直到加载满200个项目。在http节点下设置完proxy_cache_path命令,下一步在虚拟服务器配置中配置proxy_cache命令,我们可以看看proxy_cache命令的语法结构:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
proxy_cache niyueling;

可以看到proxy_cache命令很简单,就是指定了我们刚才配置的内存区。但是这里有一点需要额外注意的是:我们刚才通过配置proxy_cache_path命令的keys_zone参数配置内存区大小为10m,这并不会限制缓存数据的大小,实际上缓存数据是存储在文件系统中的特定文件的元数据副本。如果想要限制缓存数据的上限,则需要在proxy_cache_path命令中添加max_size参数设置缓存数据上限。说完了proxy_cache命令。

我们接着看看下一个命令:proxy_cache_methods,我们看下该命令语法结构:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
proxy_cache_methods[GET HEAD POST];

虚拟服务器下配置proxy_cache_methods命令可以指定该虚拟服务器下什么类型的HTTP方法可以被缓存。默认情况下GET请求及HEAD请求会被缓存,而POST请求不会被缓存。

接下来看看另外一个常见的命令:proxy_cache_valid,先贴下该命令语法结构:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
proxy_cache_valid reply_code [reply_code...] time;

这个命令很有意思,在虚拟服务器下设置该命令,它可以针对不同状态码的响应数据设置不同的缓存时间,我们可以看个简单的小例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
proxy_cache_valid 200 10m ;
proxy_cache_valid 404 1m ;
proxy_cache_valid 302 5m ;

我们通过上面的命令就可以设置200状态码的缓存时间为10分钟,302重定向的缓存时间为5分钟,404的缓存时间为1分钟。如果想为所有状态码定义相同缓存时间,就可以使用any作为第一个参数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
proxy_cache_valid any 5m;

接下来看看下一个命令:proxy_cache_bypass。一样先看下语法结构:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
proxy_cache_bypass  $cookie_nocache  $arg_nocache$arg_comment;

这个命令可以配置不会向客户端响应缓存,而是直接将请求转发给后端服务进行请求数据。可以通过上述命令配置需要绕过缓存的请求URL,也就是说URL中包含该配置的值,则这次请求会直接跳过缓存直接请求后端服务去获取数据。

接下来还有最后一个比较常用的命令:proxy_cache_min_uses。先贴下语法结构:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
proxy_cache_min_uses 2;

这个命令可以设置当某请求最少响应几次后会被缓存。若我设置为2则表示每个请求最少被请求2次后会加入到缓存中。

Nginx清除缓存

如果缓存过期则需要从缓存中删除过期的缓存文件,防止新旧缓存出现交错出错,当Nginx接收到自定义HTTP头或者PURGE请求时,缓存将会被清除。

配置缓存清除

我们在HTTP节点下创建一个新变量$purge_method来标识使用PURGE方法的请求并删除匹配的URL

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
http {
  map $request_method $purge_method {
    PURGE 1;
    default 0;
  }
}

进入虚拟服务器配置,在location中配置高速缓存,并且指定缓存清除请求命令proxy_cache_purge

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
server {
  listen 80;
  server_name www.niyueling.cn;
  location / {
    proxy_cache niyueling;
    proxy_cache_purge $purge_method;
  }
}

发送清除命令

配置proxy_cache_purge指令后需要发送PURGE请求来清除缓存。例如我们使用PURGE方式请求url:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
PURGE www.niyueling.cn/getArticle

getArticle对应的缓存中的数据将被删除。但是,这些高速缓存数据不会从缓存中完全删除,它们将保留在磁盘上,直到它们被删除为非活动状态,或由缓存清除进程处理。

限制IP访问清除命令

清除缓存这种命令一般需要权限才可进行操作,所以我们一般需要配置允许发送缓存清除请求的IP地址:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
geo $purge_allowed {
 default 0; 
 49.235.28.88 1; 
 192.168.1.100/24 1; 
}
map $request_method $purge_method {
 PURGE $purge_allowed;
 default 0;
}

Nginx接收到清除缓存请求时,Nginx检查客户端IP地址,若IP地址已经获得清除缓存权限,则$purge_method设置为$purge_allowed,值为1表示允许清除缓存,值为0表示表示IP地址未获得权限。

从缓存中完全删除文件

刚才说过了高速缓存数据不会从缓存中完全删除,它们将保留在磁盘上,直到它们被删除为非活动状态,或由缓存清除进程处理。要完全删除与getArticle相匹配的缓存数据,需要在proxy_cache_path添加参数purger,该参数表示永久的遍历所有缓存条目,并删除与通配符相匹配的条目。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
proxy_cache_path /data/cache keys_zone=niyueling:10m purger=on;

字节缓存

当我们请求一个大文件时,因为请求比较耗时,当有下一个请求来临时将不得不等待整个大文件被下载并放入高速缓存。Nginx用缓存片模块填充高速缓存。可以将大文件分为较小的切片,每个范围请求选择将覆盖所请求范围的特定切片,并且如果此范围切片仍未缓存,就将其放入缓存中。启用字节范围缓存需要注意两个条件是否满足:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
确保Nginx是使用模块编译的。
使用slice指令指定切片的大小。

可以使用slice命令指定切片大小:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
location / {
 slice 1m;
}

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

接着将$slice_range变量加入到缓存键中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
proxy_cache_key $uri$is_args$args$slice_range;

使用206状态代码缓存响应,缓存有效期30m

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
proxy_cache_valid 206 30m;

然后设置Range头传递$slice_range变量来将传递范围请求:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
proxy_set_header Range $slice_range;

字节缓存小案例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
location / {
 slice 1m;
 proxy_cache niyueling;
 proxy_cache_key $uri$is_args$args$slice_range;
 proxy_set_header Range $slice_range;
 proxy_cache_valid 206 30m;
}

缓存清除小案例

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
http {
  proxy_cache_path /data/cache keys_zone=niyueling:10m purger=on;
  map $request_method $purge_method {
    PURGE 1;
    default 0;
  }
  
  server {
    listen 80;
    server_name www.niyueling.cn;
    location / {
      proxy_cache niyueling;
      proxy_cache_purge $purge_method;
    }
  }
 
  geo $purge_allowed {
    default 0;
    49.235.28.88 1; 
    192.168.1.100/24 1; 
  }
 
  map $request_method $purge_method {
    PURGE $purge_allowed;
    default 0;
  }
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-09-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序猿周先森 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
Mac shell(fish) javac 中文乱码
通过用户的环境变量(~/.bash_profile)去改.写入文件.bash_profile  vim ~/.bash_profile
obaby
2023/02/23
5530
theos iosopendev各种蛋疼的问题
1.xcrun: error: unable to find utility “codesign_allocate”, not a developer tool or in PATH
obaby
2023/02/23
4560
让Mac OS终端支持高亮显示
编辑用户当前目录下的.bash_profile文件即可,如果没有可以创建一个。在文件中输入如下的内容,保存之后重启即可。
obaby
2023/02/24
1.7K0
Charles V4.6.1 序列号
Charles其实是一款代理服务器,通过成为电脑或者浏览器的代理,然后截取请求和请求结果达到分析抓包的目的。该软件是用Java写的,能够在Windows,Mac,Linux上使用。开发iOS都在Mac系统上吧,安装Charles的时候要先装好Java环境。这么好的软件不是免费的,官网要好几十刀呢,我这里有一个Mac上的破解版,点击这里下载,当然不是最新版的。如果你想体验最新版,Charles是提供试用的。
obaby
2023/02/22
9100
iPhone5 QQ音乐文件导出
不过随便去目录下搜索了下还是能找到文件在什么地方的,什么tm0,tm3之类的文件,全部下载下来就行了。
obaby
2023/02/23
5500
iOS https(SSL/TLS)数据捕获
要捕获iPhone上的appstore的数据还真的没那么容易,以前介绍的那些使用代理手工导入证书的方法已经完全失效了,结果就是安装证书之后再打开appstore也无法正常的建立连接。按照我的分析其实是appstore在检测证书无效之后直接就没有发起任何的请求(可以通过wireshark抓包查看网络数据) 随之而来的是第二种方法,patch ssl证书校验函数,根据这个原理实现的有两个工具,一个是ssl kill switch,另外一个是trustme。原理都是一样的,并且也非常的简单,按照作者的说法是truestme实现的更底层一些。但是很不幸的是,结局是同样的悲哀的,在iOS6之后这个东西也是失效了。 其实我这里要说的方法也比较简单,如果阅读过上面两个工具的源代码(请自行搜索相关代码),并且理解mac os/iOS 下https实现的相关原理,那么也就自然的想到hook发送和接收函数的方法来捕获数据了。 需要关心的函数只有两个sslread和sslwrite: 代码:
obaby
2023/02/23
5460
海信(Hisense)60E3F 安装第三方应用
老家的房子装修完一段时间了,最近准备家电。于是就想着把现在用的电视替换下来,带回老家用。之所以有这么个决定是因为1在老家呆的时间有限,并且现在用的电视已经四五年了,系统非常卡。但是如果连接有线电视看基本没有任何问题,尺寸也足够55寸。于是就从二手东买了一个新的进来,做完安装好之后,想给电视装个ds file。结果拷贝到u盘之后发现文件不显示。无法安装。
obaby
2023/02/22
8050
Litespeed Cache https模式下css/js 加载失败
安装litespeed插件并且开启之后,发现原有的页面样式丢失了。导致这个问题的原因在于虽然访问的是https的链接,但是资源文件依旧是http协议加载的,所以就直接挂掉了。解决这个问题最简单的办法应该是开启全站https,但是我并不想这么干,想依旧提供http访问的能力。于是找各种解决方法,网上提供的解决方案包含但不限于下面这几种:
obaby
2023/02/22
6400
Putty OpenSSH SSH-2 private key (old PEM format)
当使用putty登陆时,会提示这个错误,这是因为key的格式不兼容putty导致的,需要转换一下
obaby
2023/02/22
8860
SQLiteMaestro v11.3.0.1 Crack Guide
其实这个东西也不算是破解掉了,因为外面的那个aspr的壳没有脱掉,于是借助工具创建了一个带壳的loader。其实东西如果脱壳了,那么破解就非常简单了。如果不知道怎么脱这个壳,参考这里。如果已经脱掉壳了。那么破解也就非常简单了。这里就简单的贴几条代码,看懂了就看,看不懂就算了。为了兑现前面说的话,这里不再提供loader下载,大家去别的地方找吧。不好意思。
obaby
2023/02/24
2160
OSX app 启动后在程序坞不显示
用回mac之后发现各种神奇的问题,比如cocos运行之后在程序坞中找不到,开的窗口多了之后每次想找到他得翻半天(主要是不会各种神奇的快捷键)。
obaby
2023/02/24
6010
两道C语言题目
1:给定一个升序排列的数组,要求插入一个新数据后仍然升序输出,例如:原数据为:1,6,9,23,56,95插入新的一个数据50后输出变为:1,6,9,23,50,56,95.
obaby
2023/02/28
6240
两道C语言题目
.vimrc 配置文件
Mac OS下默认的vim配置文件也够蛋疼的,什么都没有。这个发一个,不是我自己写的 😉 ,其实本来应该是那个地方的来着我也忘了,去掉了一行不支持的配置。 最简单的办法是在用户目录下执行 wget http://www.h4ck.org.cn/.vimrc 当然也可以复制下面的代码自己创建这个文件: "========================================================================= " DesCRiption: vimrc for
obaby
2023/02/23
9500
是UPS吖(二)–-群晖
开篇当然还是最喜欢的小姐姐啊。其实ups的安装还是非常简单的,不过后面的插孔都是3插,机柜上就安装了一排机柜插座,导致出现一个问题就是机柜内很多双口插头没地方插,本来想把边上的插排撤掉的,但是明显不行啊,两个光纤转换器插头+路由器+交换机的插头都没地方插,于是就把插排又给按上了。安装之后的效果就是下面这个样子啦。
obaby
2023/02/22
7300
深入解析Xcode无证书编译以及真机调试
从标题就可以看出文章的主要内容了,一个是无证书编译,另外一个则是真机调试。网上关于此类文章很多,但是基本都是抄来抄去的,也没一个详细的说明具体这么做的原因。并且配置的步骤也基本一致,没什么太大的区别。
obaby
2023/02/23
1.9K0
Plist Editor Pro(plist文件编辑工具)V2.5[64 bit] for Windows Crack
链接:https://pan.baidu.com/s/1CrzI_9GRjquUgQy4LIL0BA 密码:1t70
obaby
2023/02/24
1.9K0
再谈Mac 终端的高亮
也不知道为什么苹果不愿意默认情况下让那个终端支持高亮,每次都要非诚蛋疼的重新配置,哈哈,其实问题的关键是我用的不是mac的主机,用的虚拟机跑的mac,现在还是挺顺畅的。今天这里要介绍的不是配置脚本,是另外的一个终端工具,fish。嘎嘎
obaby
2023/02/23
7930
Windows git log 中文乱码
文章很多,但是没啥重点,问题的根源在于less的编码问题。所以只需要一步解决,设置 LESSCHARSET=utf-8 环境变量。
obaby
2023/02/24
7350
批处理 激活virtualenv 并且运行Python 命令
* 网站名称:obaby@mars * 网址:https://h4ck.org.cn/ * 本文标题: 《批处理 激活virtualenv 并且运行Python 命令》 * 本文链接:https://h4ck.org.cn/2019/01/%e6%89%b9%e5%a4%84%e7%90%86-%e6%bf%80%e6%b4%bbvirtualenv-%e5%b9%b6%e4%b8%94%e8%bf%90%e8%a1%8cpython-%e5%91%bd%e4%bb%a4/ * 转载文章请标明文章来源,原文标题以及原文链接。请遵从 《署名-非商业性使用-相同方式共享 2.5 中国大陆 (CC BY-NC-SA 2.5 CN) 》许可协议。
obaby
2023/02/24
8430
Mac m1 安装Wine/WineHQ
在m1上安装尝试了比较多的教程,基本都失败了。直到看到这篇文章:https://git.boc-group.eu/adoxxosports/adoxx-15-64bit/-/blob/master/Installation%20Manual%20(M1)%20Wine%20und%20Azure%20SQL
obaby
2023/02/22
8.1K0
相关推荐
Mac shell(fish) javac 中文乱码
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档