强缓存

一、Expires(http1.0 规范)

Expires 的值为一个绝对时间的 GMT 格式的时间字符串,例如 Mon,10 Jun 2015 21:31:24 GMT。若发送请求的时间在 expires 之前,则本地缓存有效;否则,将发送请求至服务器以获取资源。

二、cache-control(http1.1 出现的 header 信息)

通过 max-age 值进行判断,它是一个相对值。浏览器依据第一次的请求时间和 Cache-Control 设置的有效期,计算出资源过期时间。再将该过期时间与当前时间进行比较,若请求时间在过期时间之前,则能命中缓存,否则不行。Cache-Control 的设置由服务器完成,前端无需进行任何操作。

Cache-Control 的常用选项
选项 含义
max-age=100 缓存 100 秒后过期,资源缓存在本地。
no-cache 不使用本地缓存,使用协商缓存。先与服务器确认返回的响应是否被更改,若之前的响应中存在 ETag,则请求时会与服务端验证。若资源未被更改,则可避免重新下载。
no-store 所有内容都不会被缓存,既不使用强制缓存也不使用协商缓存。每次用户请求该资源,都会向服务器发送一个请求,服务器再返回资源。
public 可以被所有的用户缓存,包括客户端和代理服务器。
private 只能被客户端缓存,不允许 CDN 等中继缓存服务器对其缓存。
s-maxage 覆盖 max-age,作用域与 max-age 一样,但只用于代理服务器中缓存。

在浏览器下一次请求同样的文件时,浏览器会检查 max-age 是否过期。若未过期,则直接从本地缓存中获取资源,不会向服务器再次发起请求;若过期,浏览器会像第一次一样向服务器发起请求。一旦使用强缓存且未过期,就不会再向服务器发起请求。

Cache-Control 常用选项的选择

三、弊端

采用强缓存方式,页面加载速度最快,性能也很好。然而,在此期间若服务器端的资源被修改,页面将无法获取到最新资源,因为此时不会再向服务器发送请求,而是直接使用本地缓存的数据。这种情况在开发中经常遇到,例如修改了页面上的某个样式,但页面刷新后却未生效,这通常是因为走了强缓存。此时进行强制刷新(ctrl+F5)即可。

协商缓存

协商缓存是在强制缓存失效后,浏览器携带缓存标志向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程。

一、ETag

资源唯一标识。浏览器请求时会携带 ETag,服务端收到请求后会与本地文件进行比较,若一致则返回 304 Not Modify。

二、If-None-Match

客户端发送的匹配 Etag 标识符

三、Last-modified

表示服务器本地记录中的文件最后修改时间,由服务器发送给客户端

四、If-Modified-Since

表示浏览器缓存记录中该文件的最后服务器修改时间,由客户端发送给服务器

反向代理-缓存篇-CSDN博客

如果时间一致,那么返回HTTP状态码304(不返回文件内容),客户端接到之后,就直接把本地缓存文件显示到浏览器中
如果时间不一致,就返回HTTP状态码200和新的文件内容,客户端接到之后,会丢弃旧文件,把新文件缓存起来,并显示到浏览器中

浏览器的三种刷新方式

  • 回车刷新或a链接
    看cache-control对应的max-age是否仍然有效,有效则直接from cache,若cache-control中为no-cache,则进入缓存协商逻辑
  • F5刷新
    去掉cache-control中的max-age或直接设置max-age为0,然后进入缓存协商逻辑
  • ctrl+F5
    去掉cache-contro和协商头,强制刷新

静态资源部署策略-资源(一)

  1. css,js,img等元素使用带版本号部署,例如a.js?v=1.0 不便利且维护困难
  2. css,js,img等元素使用带摘要部署,例如a.js?v=45edw 存在先部署html还是先部署资源的覆盖问题
  3. css,js,img等元素使用摘要做文件名部署,例如45edw.js,新老版本并存且可回滚,资源部署完后再部署html

静态资源部署策略-html(二)

  1. 对应静态资源保持生命周期内不会变,max-age可设置的很长无视失效更新周期
  2. html文件设置no-cache或较短max age,以便于更新
  3. html文件仍然设置较长的max age,依靠动态的获取版本号请求发送到后端,异步下载最新的版本号的html后展示渲染在前端

动态请求静态化处理

动态请求也可以静态化成ison资源推送到cdn上
依靠异步请求获取后端节点对应资源状态做紧急下架处理
可通过跑批紧急推送cdn内容以使其下架等操作

架构改进-全页面静态化

用户请求ajax,数据回来之后渲染难道static中的html模板里;
其实用户不关心H5请求过来的是ajax还是静态资源,考虑将两者结合到一起,这便引出了页面静态化;

定义:在服务端完成html,css,甚至is的load渲染成纯html文件后直接以静态资源的方式部署到cdn上

交易验证优化

用户风控策略优化:策略缓存模型化
活动校验策略优化:引入活动发布流程,模型缓存化,紧急下线能力

数据库行锁性能优化-版本一🥩

将扣减库存功能移植到redis中

  • 活动发布同步库存进缓存中
  • 下单交易减缓存库存(会存在数据不一致的问题)

数据库行锁性能优化-版本二🥩

增加mq消息队列

  • 活动发布同步库存进缓存中
  • 下单交易减缓存库存(会存在数据不一致的问题)
  • 异步消息扣减数据库内库存

异步同步数据库

存在的问题

  1. 异步消息发送失败
  2. 扣减操作执行失败
  3. 异步消息后面的流程,比如下单失败了,无法正确回补库存

缺少一条机制保证库存扣减的正确性

回查机制-库存操作流水

  • 主业务数据:master data
  • 操作性数据:log data
create stock_log {
stock_log_id int;
item_id int;
count int;
status int;
}

库存数据库最终一致性保证

  • 方案
    • 引入库存操作流水
    • 引入事务性消息机制
  • 问题.
    • redis不可用时如何处理-(2)扣减流水错误如何处理

库存售罄

  • 库存售罄标识
  • 售罄后不去操作后续流程
  • 售罄后通知各系统售罄
  • 回补上新

现有缺陷

  • 秒杀下单接口会被脚本不停的刷
  • 秒杀验证逻辑和秒杀下单接口强关联,代码冗余度高
  • 秒杀验证逻辑复杂,对交易系统产生无关联负载

秒杀令牌原理

  1. 秒杀接口需要依靠令牌才能进入
  2. 秒杀的令牌由秒杀活动模块负责生成
  3. 秒杀活动模块对秒杀令牌生成全权处理,逻辑收口
  4. 秒杀下单前需要先获得秒杀令牌

队列泄洪原理

  1. 排队有些时候比并发更高效(例如redis单线程模型innodb mutex key等)
  2. 依靠排队去限制并发流量
  3. 依靠排队和下游拥塞窗口程度调整队列释放流量大小
  4. 支付宝银行网关队列举例