nginx 简单实践:Web 缓存【nginx 实践系列之三】
〇、前言
本文为 nginx 简单实践系列文章之二,主要简单实践了两个内容:正向代理、反向代理,仅供参考。
关于 Nginx 基础,以及安装和配置详解,可以参考博主过往文章:
https://www.cnblogs.com/hnzhengfy/p/Nginx.html
一、强制缓存、协商缓存
1.1 强制缓存(强缓存)
强制缓存指的是当用户请求一个资源时,浏览器直接从本地缓存中读取数据而不向服务器发送任何请求。
这种缓存机制主要依赖于 HTTP 响应头中的 Cache-Control 和 Expires 字段。
Expires:这是 HTTP/1.0 引入的一个头部字段,它指定了资源在该时间之前被认为是有效的。例如,Expires: Wed, 21 Oct 2025 07:28:00 GMT。但是,由于 Expires 依赖于客户端的时间设置,可能出现非预期的状况。
Cache-Control:HTTP/1.1 引入了更为强大的 Cache-Control 头部,提供了更多控制缓存行为的指令,如下表:
值 | 含义 |
no-store | 禁止缓存(强缓存和协商缓存),客户端不存储任何值 |
no-cache | 禁止强缓存,需要重写验证(可以理解为禁止强缓存,启用协商缓存) |
private | 私有缓存,禁止中间人(比如 CDN 等代理缓存) |
public | 共享缓存,允许中间人缓存 |
max-age | 资源可以被缓存的最大时间,单位:秒,是一个相对时间,优先级高于 Expires,示例(缓存两分钟):max-age=120 |
s-maxage | 用于共享缓存,单位:秒,如果在其有效期内,不去访问 CDN 等。s-maxage 会覆盖 max-age 和 Expires |
must-revalidate | 缓存使用陈旧资源时,必需先验证状态 |
强缓存的优势:
- 减少网络请求:浏览器可以直接使用本地缓存中的资源,无需再次向服务器发起请求,从而减少了网络往返次数,提升了页面加载速度。
- 降低服务器负载:由于减少了对服务器的请求,服务器的压力也随之减小,有助于提高服务器的整体性能和稳定性。
- 节省带宽:避免了重复下载相同的数据,节省了用户的网络带宽,尤其对于移动设备或在带宽有限的情况下尤为重要。
- 提升用户体验:加速页面加载时间,尤其是对于静态资源如图片、CSS 和 JavaScript 文件等,能够显著改善用户体验。
强缓存的劣势:
- 可能展示过期内容:如果缓存策略设置不当,可能会导致用户看到过期的内容。例如,如果资源更新了但缓存尚未过期,用户将继续看到旧版本的资源,直到缓存失效。
- 缺乏灵活性:强制缓存的时间是预先设定好的,无法根据实际情况动态调整。这意味着即使服务器上的资源已经更新,只要客户端缓存未过期,用户就看不到最新的内容。
- 需要精确配置:正确配置缓存策略需要一定的专业知识,尤其是在处理不同类型的资源时(如静态资源与动态生成的内容),错误的配置可能导致缓存命中率低或频繁的缓存失效问题。
- 难以应对紧急更新:在某些情况下,比如发现安全漏洞或需要立即推送的重要更新,强制缓存可能会成为障碍,因为用户可能长时间看不到最新的修复或更新。
在实际应用中,通常会结合使用强制缓存和协商缓存,以达到既快速又可靠的缓存效果。例如,对于不经常变化的静态资源可以使用较长的缓存时间,而对于可能频繁更新的内容则采用较短的缓存时间或者使用协商缓存机制。
1.2 协商缓存
协商缓存(也称为验证缓存)是一种 HTTP 缓存机制,它在强制缓存失效后使用。
在这种情况下,浏览器会携带特定的缓存标识(如 ETag 或 Last-Modified)向服务器发送请求,询问资源是否有更新。如果资源没有变化,服务器将返回一个 304 Not Modified 状态码,指示客户端可以继续使用本地缓存;如果资源有变化,则服务器返回新的资源。
协商缓存主要依赖于 值标记法(ETag、If-None-Match)和比较最后修改时间法(Last-Modified、If-Modified-Since)两种头部字段来实现。
值标记法(ETag、If-None-Match):
- ETag:由服务器生成并返回给客户端的一个唯一标识符,通常基于文件内容的哈希值。每当资源发生变化时,ETag 也会随之改变。
- If-None-Match:当客户端再次请求资源时,会在请求头中带上之前获取的 ETag 值。服务器收到请求后,会比较当前资源的 ETag 与请求中的 If-None-Match 值。如果两者相同,说明资源未变,服务器返回 304 Not Modified(未更改,缓存可用);否则,服务器返回新的资源及其新的 ETag。
比较最后修改时间法(Last-Modified、If-Modified-Since):
- Last-Modified:服务器告诉客户端资源最后修改的时间。例如,Last-Modified: Wed, 21 Oct 2025 07:28:00 GMT。
- If-Modified-Since:客户端在后续请求中会带上这个时间戳。服务器接收到请求后,检查资源的最后修改时间 Last-Modified 是否晚于 If-Modified-Since 指定的时间。如果是,服务器返回新资源;如果不是,服务器返回 304 Not Modified(未更改,缓存可用)。
协商缓存的优势:
- 确保数据新鲜度:通过与服务器进行验证,确保用户始终能够获取到最新的资源,避免了因缓存过期而看不到最新内容的问题。
- 节省带宽:如果资源没有变化,服务器只需返回一个小的 304 Not Modified 响应,而不需要重新传输整个资源,从而节省了带宽。
- 灵活性:相比强制缓存,协商缓存提供了更高的灵活性,允许根据实际资源的变化情况动态调整缓存策略。
协商缓存的劣势:
- 增加网络开销:即使资源没有变化,每次请求都需要与服务器进行一次验证,这增加了少量的网络开销。
- 复杂性较高:需要正确设置和管理 ETag、Last-Modified 等头部字段,增加了配置和维护的复杂性。
- 性能略逊于强缓存:虽然节省了带宽,但相比直接从缓存中读取资源,协商缓存仍需要一次网络往返,因此性能稍逊一筹。
通过合理地结合使用强制缓存和协商缓存,可以根据不同的需求优化网站的性能和用户体验。
对于不常变化的静态资源,可以优先考虑使用强制缓存;而对于那些需要保持最新状态的资源,则应采用协商缓存。
二、通过 nginx 配置实现 Web 缓存
2.1 强缓存的实现:Cache-Control
Expires 可能造成误差,因此不再进行示例测试。由于 Expires 配置是后端返回给客户端的一个时间戳,取自服务器时间,当客户端发送请求时,采用客户端的当前时间进行比较,如果两边时间有误差就会造成数据不一致的异常情况。
Cache-Control 的优先级高于 Expires,Expires 是 http1.0 的产物,而 Cache-Control 是 http1.1 的产物,两者同时存在的时候 Expire 会被 Cache-Control 的 max-age 覆盖,在不支持 http1.1 的情况下可能就需要 Expires 来保持兼容。
nginx 配置示例:
server {
listen 8888;
server_name www.testczzj.com;
#charset utf-8;
#charset koi8-r;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
add_header Cache-Control max-age=500; # 缓存有效期配置为 500 秒
proxy_pass http://www.testczzj.com:5000;
}
}
如下图请求结果:(响应头中包含了强缓存配置项 Cache-Control)
如下图针对文件 bootstrap.min.css 的二次请求详情:
2.2 协商缓存实现:Cache-Control:no-cache
客户端每次请求都会向服务端发起,若没更新则返回 304,若有更新就正常返回 200。
nginx 配置,其实就是修改了 Cache-Control 这个配置项:
server {
listen 8888;
server_name www.testczzj.com;
#charset utf-8;
#charset koi8-r;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
add_header Cache-Control no-cache; # 配置为协商缓存
proxy_pass http://www.testczzj.com:5000;
}
}
如下图,首次加载是从服务器拉取全部数据,待第二次刷新时,在服务端数据未发生变更的情况下,返回 304,效率大大提高:
如下图针对文件 bootstrap.min.css 的二次请求详情:
2.3 无缓存:Cache-Control:no-store
nginx 配置如下:
server {
listen 8888;
server_name www.testczzj.com;
#charset utf-8;
#charset koi8-r;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
add_header Cache-Control no-store; # 配置无缓存
proxy_pass http://www.testczzj.com:5000;
}
}
每次请求都是从服务端取数据,如下图:
参考:https://blog.csdn.net/JarryNeverGiveup/article/details/131060939
https://segmentfault.com/a/1190000040748678
nginx 简单实践:Web 缓存【nginx 实践系列之三】的更多相关文章
- 用代码来实践Web缓存
Web缓存是可以自动保存常见文档副本的HTTP设备.当Web请求抵达缓存时,如果本地有"已缓存的副本",就可以从本地存储设备而不是原始服务器中提取这个文档. 上面是<HTTP ...
- nginx的web缓存服务环境部署记录
web缓存位于内容源Web服务器和客户端之间,当用户访问一个URL时,Web缓存服务器会去后端Web源服务器取回要输出的内容,然后,当下一个请求到来时,如果访问的是相同的URL,Web缓存服务器直接输 ...
- Nginx简单总结
NGINX简单总结 特点总结 nginx有一个master进程和多个worker进程,master进程是主要用来管理worker进程,管理的内容包括以下内容:接收来自外界的信号,向各个woker进程发 ...
- Nginx部署及Web基础
目录 Nginx部署及Web基础 Nginx简介 Nginx特点 Web服务 Web服务器软件 Nginx和Apache对比图 部署Nginx yum安装 编译安装 平滑增加Nginx模块 Nginx ...
- Nginx之(一)Nginx是什么
Nginx("engine x")是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器.由俄罗斯的程序设计师Igor Sysoev所开发,供俄国大 ...
- 基于nginx+lua+redis高性能api应用实践
基于nginx+lua+redis高性能api应用实践 前言 比较传统的服务端程序(PHP.FAST CGI等),大多都是通过每产生一个请求,都会有一个进程与之相对应,请求处理完毕后相关进程自动释放. ...
- Nginx配置支持https协议-应用实践
Nginx配置支持https协议-应用实践 https简介 HTTPS 是运行在 TLS/SSL 之上的 HTTP,与普通的 HTTP 相比,在数据传输的安全性上有很大的提升. TLS是传输层安全协议 ...
- Nginx+Memcached+Tomcat集群配置实践(Sticky Session)
准备工作 创建一个简单的web应用,名为session.其中有两个页面,分别如下所示: 页面login.jsp <%@ page language="java" conten ...
- nginx高性能WEB服务器系列之三版本升级
nginx系列友情链接:nginx高性能WEB服务器系列之一简介及安装https://www.cnblogs.com/maxtgood/p/9597596.htmlnginx高性能WEB服务器系列之二 ...
- Nginx反代服务器基础配置实践案例
转载自:https://www.bilibili.com/read/cv16149433?spm_id_from=333.999.0.0 方式1: 轮询 RR(默认轮询)每个请求按时间顺序逐一分配到不 ...
随机推荐
- Rider离线使用Nuget包的方法
有时候,我们的开发环境可能没有网络,vs也不太好安装. 这时候我们就可以使用Rider.但是没有Nuget的话,很多东西用起来很复杂. 所以这里介绍一下Rider离线配置Nuget的方法. 从Nuge ...
- 聊一下怎么十分钟速水CVE
题目是真的.今天晚上刚接触关于CVE的审计和提交.只能说:牛逼的是真牛逼,水的是真水. 我接下来教你,怎么在10分钟里找到一个CVE的中危漏洞并且提交.然后你就可以去咸鱼接单了,一个一铂快 打开htt ...
- 语音转文字-Microsoft Azure Speech Service与Web Speech API实战
简介 在现代技术驱动的世界中,语音识别已成为人机交互的重要方式.Microsoft Azure Speech Service 提供了强大的语音转文本功能,允许开发者轻松地将语音数据转换为文本.本文将指 ...
- ORACLE本地磁盘备份恢复
1.部署新备份磁盘(源和目标) [oracle@cmxdb /ora_bak]$ mkdir -p /oracle/rmanback [oracle@cmxdb /ora_bak]$ chown -R ...
- 【C++】static 知识整理 【静态与局部静态】
目录 类外 类内 局部静态 local static 类外 类内 类外 C++的静态可以分为两种情况来讨论:在类外和在类内. 对于静态变量/函数,链接将只在内部 (如果不用static,那么在不同文件 ...
- 问题解决:windows主机开机不插屏幕不能自动进入桌面
操作系统一般都有这种设定,不论是windows还是Linux系统,那就是主机开机不插屏幕不能自动进入桌面操作系统一般都有这种设定,不论是windows还是Linux系统,那就是主机开机不插屏幕不能自动 ...
- Mysql8忽略大小写的解决方案
一.删除服务器数据文件 由于8.0没法设置参数后重启(失败),所以必须删掉老库,重新启动才行. 切记::本步骤要删掉老库所有资料,如果是数据库当前有用,请做好备份,再进行操作. systemctl ...
- 题解:P11007 『STA - R7』Odtlcsu
有个很显然的结论,题目中的 $x$ 与 $y$ 奇偶性相同. 有个更简单的证明,奇数的平方为奇数,偶数的平方为偶数,所以 $x$ 与 $y$ 奇偶性相同. 思路就显而易见了,考虑构造一个长度为 $y$ ...
- 从混沌到秩序:Python的依赖管理工具分析
Python 的依赖管理工具一直没有标准化,原因主要包括: 历史发展的随意性:Python发展早期对于依赖管理的重视程度不足,缺乏从一开始就进行统一规划和设计的意识 社区的分散性:Python社区庞大 ...
- 2.猿人学爬虫攻防第二题 JS 混淆 动态cookie
题目链接:请点击 抓取到发布日热度的值,计算所有值的加和 1.分析网页 由于是动态Cookie,为了避免其他Cookie的影响,所以使用浏览器的无痕模式进行调试,按f12并选中[Preserve lo ...