缓存集成
概述
1、Cache:数据交换的缓冲区
场景 | 作用 |
操作系统磁盘缓存 | 减少磁盘机械操作 |
数据库缓存 | 减少文件系统的IO操作 |
应用程序缓存 | 减少对数据库的查询 |
Web 服务器缓存 | 减少对应用服务器请求次数 |
浏览器缓存 | 减少与后台的交互次数 |
2、优点
(1)减少数据传输,节省网络流量,加快响应速度,提升用户体验
(2)减轻服务器压力
(3)提供服务端的高可用性
3、缺点
(1)数据的不一致
(2)增加成本
4、多级缓存
(1)静态资源缓存
(2)浏览器缓存
(3)CDN缓存
(4)正向代理缓存
(5)反向代理缓存
(6)Nginx 内存缓存
(7)外置内存缓存
(8)上游服务器应用缓存
缓存处理
1、Web 缓存
(1)一个 Web 资源存在于 Web 服务器和客户端(浏览器)之间的副本
(2)缓存根据访问请求,保存输出内容的副本
(3)当下一个请求访问时,如果是相同 URL,缓存会根据缓存机制,决定是直接使用副本响应访问请求,还是向源服务器再次发送请求
2、Web 缓存种类
(1)客户端缓存:浏览器缓存
(2)服务端缓存:Nginx / Redis / Memcached 等
浏览器缓存
1、优点
(1)成本最低的一种缓存实现
(2)减少网络带宽消耗
(3)降低服务器压力
(4)减少网络延迟,加快页面打开速度
2、HTTP 协议中与页面缓存相关字段
header | 说明 |
Expires | 缓存过期的日期和时间 |
Cache-Control | 设置和缓存相关的配置信息 |
Last-Modified | 请求资源最后修改时间 |
ETag | 请求变量的实体标签的当前值,比如文件 MD5 值 |
3、强制缓存
(1)直接从本机读取,不请求服务器
(2)Cache-Control、Expires
(3)Cache-Control 作为响应头信息,可以设置如下值
标记 | 类型 | 说明 |
must-revalidate | 请求和响应 | 可缓存,但必须再向源服务器进行确认。当缓存过期后,必须回源重新请求资源。比 no-cache 更严格。因为 HTTP 规范是允许客户端在某些特殊情况下直接使用过期缓存的,比如校验请求发送失败的时候。那么带有 must-revalidate 的缓存必须校验,其他条件全部失效。 |
no-cache | 请求头 | 缓存前必须确认其有效性。可以使用本地缓存,但是必须发送请求到服务器回源验证 |
no-store | 请求和响应 | 不缓存请求或响应的任何内容。禁用缓存 |
no-transform | 代理不可更改媒体类型 | |
public | 响应头 | 可向任意方提供响应的缓存 |
private | 响应头 | 仅向特定用户返回响应 |
proxy-revalidate | 请求和响应 | 要求中间缓存服务器,对缓存的响应有效性再进行确认 |
max-age=<秒> | 请求和响应 | 响应最大 Age 值,文件可以在浏览器中缓存的时间,以秒为单位 |
s-maxage=<秒> | 请求和响应 | 公共缓存服务器响应的最大 Age 值,用户代理层缓存,CDN 下发,当客户端数据过期时会重新校验 |
max-stale | 请求和响应 | 缓存最大使用时间,如果缓存过期,但还在这个时间范围内,则可以使用缓存数据 |
min-fresh | 请求和响应 | 缓存最小使用时间 |
proxy-revalidate | 请求和响应 | 那么只使用缓存内容,如果没有缓存,则 504 getway timeout |
stale-while-revalidate | 响应 | 表示在指定时间内可以先使用本地缓存,后台进行异步校验 |
stale-if-error | 响应 | 在指定时间内,重新验证时返回状态码为 5XX 的时候,可以用本地缓存 |
only-if-cached | 响应 | 那么只使用缓存内容,如果没有缓存 则504 getway timeout |
(4)在浏览器和服务器端验证文件是否过期的时候,浏览器在二次请求的时候会携带 IF-Modified-Since 属性
(5)Expires:过期时间
4、协商缓存
(1)发送请求 header 中携带 Last-Modified,服务器可能会返回 304 Not Modified
(2)HTTP/1.1 支持 last-modified、etag
(3)在 HTTP 协议中,If-Modified-Since 和 If-None-Match 分别对应 Last-Modified 和 ETag(Entity Tag)
(4)HTTP 中并没有指定如何生成 ETag,哈希是比较理想的选择
(5)在计算 Etag 时,会产生 CPU 耗费,所以也可以用时间戳,但直接使用 Last-Modified 即可
(6)ETag:用来校验用户请求的资源是否有变化,作用和 last-modified 类似,区别是 last-modified 精确到秒,ETag 可以用 hash 算法来生成更精确的比对内容
(7)当用户首次请求资源时,返回给用户数据、200 状态码,并生成 ETag,再次请求时,服务器比对 ETag,没有发生变化,则返回 304
5、Cache-Control 直接通过不请求来实现,ETag 发请求实现,只不过服务器根据请求内容是否变化,来判断是否返回请求的资源
6、执行流程
(1)用户首次通过浏览器,发送请求到服务端获取数据,客户端没有对应缓存,所以需要发送 request 请求来获取数据
(2)服务端接收到请求后,获取服务端的数据及服务端缓存的允许后,返回 200 成功状态码,并且在响应头上附上对应资源以及缓存信息
(3)当用户再次访问相同资源时,客户端会在浏览器的缓存目录中查找,是否存在响应的缓存文件
(4)如果没有找到对应的缓存文件,则回到(2)
(5)如果有缓存文件,判断缓存文件是否过期,过期的判断标准是 Expires,
(6)如果没有过期,则直接从本地缓存中,返回数据进行展示
(7)如果 Expires 过期,需要判断缓存文件是否发生过变化
(8)判断的两个标准:ETag(Entity Tag)、Last-Modified
(9)判断结果为未发生变化,则服务端返回 304,直接从缓存文件中获取数据
(10)如果判断为发生变化,重新从服务端获取数据,并根据缓存协商(服务端所设置的是否需要进行缓存数据的设置),来进行数据缓存
浏览器缓存相关指令
1、expires
(1)控制页面缓存的作用,通过该指令控制 HTTP 应答中的 Expires 和 Cache-Control
(2)语法
expires [modified] time;
expires epoch | max | off;
(3)默认值
expires off;
(4)位置:http、server、location
(5)time:指定过期时间,如果是负数,Cache-Control 值为 no-cache;如果为非负整数,则 Cache-Control 值为 max-age=time
(6)epoch:指定 Expires 值为 '1 January,1970,00:00:01 GMT'(1970-01-01 00:00:00),Cache-Control 值为 no-cache
(7)max:指定 Expires 值为 '31 December,2037,23:59:59 GMT'(2037-12-31 23:59:59),Cache-Control 值为 10 年
(8)off:默认不缓存
2、add_header
(1)添加指定的响应头、响应值
(2)语法
add_header name value [always];
(3)位置:http、server、location
3、etag
(1)启用 / 禁用自动生成静态资源的 ETag 响应头域
(2)语法
etag on | off;
(3)默认值
etag on;
(4)位置:http、server、location
跨域问题
1、浏览器不能执行其他网站的脚本,它是由浏览器的同源策略造成,是浏览器对 JavaScript 施加的安全限制
2、浏览器的同源策略
(1)一种约定,浏览器最核心、最基本的安全功能
(2)同源:协议、域名(IP)、端口相同即为同源
3、解决
(1)使用 add_header,添加两个头信息:Access-Control-Allow-Origin、Access-Control-Allow-Methods
(2)Access-Control-Allow-Origin:允许跨域访问的源地址信息,可以配置多个(逗号分隔)可以使用 * 代表所有源
(3)Access-Control-Allow-Methods:允许跨域访问的请求方式,值可为 GET、POST、PUT、DELETE……,可以全部设置,也可以根据需要设置,多个用逗号分隔
Web 缓存服务
1、模块:ngx_http_proxy_module
2、基于 Proxy Store 实现
(1)将 URL 及相关组合作为 Key,使用 MD5 算法对 Key 进行哈希
(2)得到硬盘上对应的哈希目录路径,将缓存内容保存在该目录中
3、支持
(1)任意 URL 连接
(2)404 / 301 / 302 等,非 200 状态码
(3)对指定 URL 或状态码设置过期时间
(4)使用 purge 命令,手动清除指定 URL 缓存
4、proxy_cache_path
(1)设置缓存文件的存放路径
(2)语法
proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [min_free=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
(3)位置:http
(4)levels:指定该缓存空间对应的目录,最多可以设置 3 层,每层取值为 1 / 2,代表该层目录的字符个数,层数取值之间使用 : 分割
(5)keys_zone:所有活动的钥匙和数据信息都存储在一个共享内存区,size 为内存存储 key(索引)最大空间,一兆字节的区域可以存储大约 8000 个钥匙
(6)max_size:磁盘存储缓存数据的最大空间
5、proxy_cache
(1)开启 / 关闭代理缓存
(2)同一区域可以在多个地方使用
(3)参数值可以包含变量(1.7.9)
(4)zone_name:指定使用缓存区的名称
(5)语法
proxy_cache zone_name|off;
(6)默认值
proxy_cache off;
(7)位置:http、server、location
6、proxy_cache_key
(1)设置 Web 缓存的 key 值(索引),Nginx 根据 key 值进行 MD5 哈希缓存到内存
(2)语法
proxy_cache_key key;
(3)默认值:该指令的值接近于字符串
proxy_cache_key $scheme$proxy_host$request_uri;
(4)位置:http、server、location
7、proxy_cache_valid
(1)对不同返回状态码的 URL,设置不同的缓存时间
(2)可以指定 any 参数来缓存任何响应码
(3)缓存的参数也可以直接在响应头中设置,这比使用指令设置缓存时间的优先级更高
(4)语法
proxy_cache_valid [code ...] time;
(5)位置:http、server、location
8、proxy_cache_min_uses
(1)设置资源被访问多少次后被缓存
(2)语法
proxy_cache_min_uses number;
(3)默认值
proxy_cache_min_uses 1;
(4)位置:http、server、location
9、proxy_cache_methods
(1)设置缓存何种 HTTP 方法
(2)语法
proxy_cache_methods GET | HEAD | POST ...;
(3)默认值
proxy_cache_methods GET HEAD;
(4)位置:http、server、location
10、proxy_cache_use_stale
(1)决定在哪些情况下可以在与代理服务器的通信中使用过期的缓存响应
(2)该指令的参数与proxy_next_upstream指令的参数一致
(3)如果不能选择处理请求的代理服务器,erroe 参数也允许使用过期缓存响应
(4)此外,updating 参数允许使用一个过期缓存响应,如果它目前正在更新。这允许在更新缓存数据时尽量减少对代理服务器的访问次数
(5)使用过期缓存响应也可以直接在响应头中启用,在响应过期后的指定秒数内,这比使用指令参数的优先级低
(6)Cache-Control 域的 stale-while-revalidate 扩展,允许使用过期缓存响应,如果它目前正在更新
(7)Cache-Control 域的 stale-if-error 扩展,允许在出现错误的情况下使用过期缓存响应
(8)为了在填充一个新的缓存元素时,尽量减少对代理服务器的访问次数,可以使用 proxy_cache_lock 指令
(9)语法
proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | http_429 | off ...;
(10)默认值
proxy_cache_use_stale off;
(11)位置:http、server、location
11、proxy_cache_background_update
(1)允许启动一个后台子请求来更新一个过期的缓存项目,同时将一个过期缓存响应返回给客户端
(2)注意,有必要允许使用正在更新的过期缓存响应
(3)语法
proxy_cache_background_update on | off;
(4)默认值
proxy_cache_background_update off;
(5)位置:http、server、location
12、proxy_cache_convert_head
(1)是否把 head 请求转换成 get 请求后,再发送给上游服务器,以便缓存 body 内容
(2)如果关闭,需要在 cache key 中添加 $request_method,以便区分缓存内容
(3)语法
proxy_cache_convert_head on | off;
(4)默认值
proxy_cache_convert_head on;
(5)位置:http、server、location
13、proxy_cache_lock
(1)当启用时,一次只允许一个请求通过向代理服务器传递请求,来填充一个根据 proxy_cache_key 指令确定的新的缓存元素
(2)对同一缓存元素的其他请求,将等待响应出现在缓存中,或者等待这个元素的缓存锁被释放,最多到 proxy_cache_lock_timeout 指令设置的时间
(3)语法
proxy_cache_lock on | off;
(4)默认值
proxy_cache_lock off;
(5)位置
14、proxy_cache_lock_age
(1)如果传递给代理服务器的最后一个填充新缓存元素的请求,在指定时间内没有完成,可以再传递一个请求给代理服务器
(2)语法
proxy_cache_lock_timeout time;
(3)默认值
proxy_cache_lock_timeout 5s;
(4)位置:http、server、location
15、proxy_cache_lock_timeout
(1)为 proxy_cache_lock 设置一个超时时间
(2)若超时,请求将被传递给代理服务器,但是,响应将不会被缓存
(3)语法
proxy_cache_lock_timeout time;
(4)默认值
proxy_cache_lock_timeout 5s;
(5)位置:http、server、location
不缓存资源
1、proxy_no_cache
(1)定义不将数据进行缓存的条件
(2)如果字符串参数中,至少有一个值不为空,并且不等于 "0",那么响应将不会被保存
(3)语法
proxy_no_cache string ...;
(4)位置:http、server、location
(5)可以和 proxy_cache_bypass 指令一起使用
2、proxy_cache_bypass
(1)设置不从缓存中获取数据的条件
(2)如果字符串参数中,至少有一个值不是空,并且不等于 "0",那么响应将不会从缓存中获取
(3)语法
proxy_cache_bypass string ...;
(4)位置:http、server、location
3、相关变量
proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;
proxy_cache_bypass $http_pragma $http_authorization;
(1)$cookie_nocache:当前请求 cookie 中,键的名称为 nocache 对应的值
(2)
缓存清除
1、方式一:直接删除对应缓存目录
2、方式二:使用第三方扩展模块:ngx_cache_purge,针对单个资源
3、proxy_cache_path
(1)purger:相关参数,实现批量删除
(2)在 inactive 参数指定的时间内,没有被访问的缓存数据会被从缓存中删除,不管它们是否过期。默认情况下,inactive 被设置为 10 分钟
ngx_cache_purge
1、proxy_cache_purge
(1)允许从代理服务器的缓存中清除选定的页面
(2)语法
proxy_cache_purge on|off|<method> [from all|<ip> [.. <ip>]]
(3)位置:http、server、location
(4)示例
http {
proxy_cache_path /tmp/cache keys_zone=tmpcache:10m;
server {
location / {
proxy_pass http://127.0.0.1:8000;
proxy_cache tmpcache;
proxy_cache_key $uri$is_args$args;
proxy_cache_purge PURGE from 127.0.0.1;
}
}
}
2、proxy_cache_purge
(1)设置缓冲区和 key,用于从代理服务器的缓存中清除选定的页面
(2)语法
proxy_cache_purge zone_name key
(3)位置:独立 location 块
(4)示例
http {
proxy_cache_path /tmp/cache keys_zone=tmpcache:10m;
server {
location / {
proxy_pass http://127.0.0.1:8000;
proxy_cache tmpcache;
proxy_cache_key $uri$is_args$args;
}
location ~ /purge(/.*) {
allow 127.0.0.1;
deny all;
proxy_cache_purge tmpcache $1$is_args$args;
}
}
}
Nginx 内存缓存:ngx_http_core_module
1、open_file_cache
(1)语法
open_file_cache off;
open_file_cache max=N [inactive=time];
(2)默认值
open_file_cache off;
(3)位置:http、server、location
(4)该指令配置一个缓存
(5)错误的缓存应该通过 open_file_cache_errors 指令单独启用
(6)max:设置缓存中元素的最大数量;当缓存溢出时,最近使用最少的(LRU)元素被移除
(7)inactive:定义一段时间,如果一个元素在这段时间内没有被访问,就会从缓存中删除;默认情况下,它是 60 秒
(8)off:禁用缓存
2、open_file_cache_errors
(1)启用 / 禁用 open_file_cache 对文件查找错误的缓存
(2)语法
open_file_cache_errors on | off;
(3)默认值
open_file_cache_errors off;
(4)位置:http、server、location
3、open_file_cache_min_uses
(1)设置在 open_file_cache 指令的 inactive 参数配置的期间内,文件描述符在缓存中保持开放所需的最小文件访问次数,即被访问到多少次后会开始缓存
(2)语法
open_file_cache_min_uses number;
(3)默认值
open_file_cache_min_uses 1;
(4)位置:http, server, location
4、open_file_cache_valid
(1)设置 open_file_cache 元素应被验证的时间,即间隔多长时间去检查文件是否有变化
open_file_cache_valid time;
(3)默认值
open_file_cache_valid 60s;
(4)位置:http, server, location
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战