一张图了解http中的缓存模型

前言

  • 缓存是一种很好的程序设计思路,大范围应用在计算机科学的各个领域,比如Redis, Http,JVM(缓存一致性)等等。所以我们可以把它当做一种思维模型来学习
  • 本文仅针对Http1.1及以后的协议,且只对http中缓存的应用做解释

缓存解决的问题

  • 加速程序的运行速度,提高效率

缓存带来的问题

使用缓存会给程序带来一定的复杂性,大概总结几个缓存带来的问题如下

  • 缓存失效时机如何确定?
  • 缓存失效后的如何更新?
  • 缓存的线程安全问题?
  • 缓存击穿后如何处理?
  • 如果有多级缓存如何配合?
    Http的缓存是一种相对简单的缓存模型,主要存在的问题是缓存失效时机,下面我们直接上图分析

图解:可以看到http其实有两层缓存(只针对get请求),一层是客户端缓存,一层是服务端缓存,那么带来了两个问题,客户端和服务端的缓存何时失效?如何控制客户端和服务端缓存的存在?

总的来说http缓存控制是通过Cache-Control这个字段来实现的

先回答第一个问题

  • 如何判断客户端缓存失效?

答:用第一次请求的响应报文的max-age字段判断

  • 如何判断服务端缓存失效?

答:客户端缓存失效之后,请求服务端,服务端通过请求报文中的If-Modified-Since字段(文件的最后修改时间)来判断要下发给客户端的文件是否过期? 但是这样的判断方式不严谨,判断一个请求资源是否失效,通过修改时间不是充分必要条件(它只能判断是否过期,不能判断是否失效),还需要有请求资源的hashcode,此时会通过请求报文中的If-None-Match字段与请求资源的hashcode比较去判断是否失效。其中If-None-Match字段是第一次请求的时候的响应报文中的eTag的值。

这里涉及到字段比较多,总结下

然后第二个问题:

  • 通过no-cache与no-store去控制,no-cache表明不用客户端缓存,no-store表明两个缓存都无效。如果客户端想使用max-age缓存,在请求报文上加上字段,如果你用的retrofit,可以这么加
kotlin 复制代码
@Headers("Cache-Control:max-age=120")
@GET("/xxx")
fun getJson(): Response<String>

总结

  • 客户端请求一个2分钟的客户端缓存
  • 服务端返回max-age = 120, 指定客户端失效时间为2分钟
  • 再两分钟后,缓存失效,请求服务端,此时比较文件和eTag == If-None-match是否一致,一直使用缓存,不一致走服务端
相关推荐
andyweike27 分钟前
Android Automotive
android
又见情义1 小时前
记一次 RK3568 Android 13 蓝牙反复重启问题的排查与修复
android
hai_android1 小时前
Kotlin Flow combine 源码剖析:一个 Channel 如何优雅合并多条流
android·java·kotlin
爱学习的程序媛3 小时前
ICMP协议详解
网络·网络协议·网络安全·通信协议·icmp·网络运维
隐擎fox3 小时前
解构无感人机验证底层机制:行为生物轨迹采样、环境评分模型与自动化对抗实战
自动化测试·python·网络协议·tcp/ip·网络爬虫
敲代码的瓦龙3 小时前
Jetpack?ViewModel!!!
android·开发语言·kotlin·android-studio
Godikov3 小时前
Android 工控终端实战:从秒级卡顿到毫秒响应,SQLite/LitePal 性能优化全记录
android
星间都市山脉5 小时前
Android16 SystemService.onBootPhase 调用时机
android·java·linux·windows·ubuntu
swithun5 小时前
不用 WebView,我用 Kotlin + Compose Multiplatform 重写 Mermaid,并做了 2048 组对拍
android·开源·kotlin
AI吃大瓜5 小时前
人脸检测和行人检测4:Android实现YOLOv8 YOLO11 YOLO26人脸检测和人体检测(含源码,可实时检测)
android·yolo·人脸检测·人体检测·行人检测·yolo26