详情页
时效性较低的数据
架构演进
页面静态化
流程
- 依赖服务有数据变化,发送 mq
- 缓存服务监听 mq,有变化时候从依赖服务获取数据
- 缓存服务将数据渲染进 html,发送到每一台 nginx 应用服务器
nginx 分发层用于负载均衡,nginx 应用层拥有 全量 的 已渲染好 的html 页面
缺点
数据要全量更新
- 一个商家的信息发生变化,他的全部数据都要更新
- 全量更新速度慢
- 数据一更新,就要把 html 模板全部重新渲染一次
- 然后再把静态化的页面发给 nginx 应用服务器
- 扩容麻烦
- 加一个 nginx 应用服务器,就需要获取全部的静态页面
动态渲染
- 依赖服务有变化,发送 mq
- 缓存服务监听 mq,有变化时从依赖服务获取数据
- 缓存服务将数据写到 redis 中
- nginx 应用服务器仅存储一份 html 模板,请求到来时,使用 lua 从 redis 获取最新数据
- nginx 分发层用于负载均衡,nginx 应用层仅有 一份 html 模板页面
缓存架构
实时数据-快速双写
- nginx 应用层的模板渲染好静态数据后,通过 Ajax 请求进行获取实时数据
- OneServer 实时数据的依赖服务非常多,需要一个 OneServer 进行代理,即给定统一的入口
- 源服务对数据进行 db + mysql 双写
- 监听源服务的数据变动
- OneServer 调用源服务的接口,获得数据
- 请求预处理
- 进行库存状态的转换,第三方运费的处理,第三方配送时效的处理、商品运费动态计算(也是其他需要计算的实时数据)
- 进行参数的转换,便于调用依赖服务的接口
- 合并接口调用,减少 ajax 异步加载次数
- 比如 ajax 请求的某几个依赖服务的接口,可以在 OneServer 中的一个接口接收,也算是请求预处理的一环
- 统一监控(hystrix)
- 统一降级(hystrix dashboard + terbine)
非实时数据-动态渲染架构
多机房部署
缓存主集群
1, 双机房
- 机房A: 一主一从对外提供服务
- 机房B: 双从,正常不对外提供服务
- 双机房原因: 避免单机房挂掉导致主集群彻底挂掉
- 机房B双从原因: 避免机房A挂掉,机房B对外提供服务时,只有一个节点会无法抗住原有一主一从的读写请求量
消息队列架构
- 任务等待队列
- 依赖服务 -> 数据同步服务(之前说的缓存服务)
- 任务排重队列
- 数据同步服务对消息做排重 -> 数据聚合服务
- 失败任务队列
- 数据同步服务写缓存、写队列可能会失败
- 数据聚合服务可能写缓存可能会失败
- 这些队列需要带上时间戳,避免被复写旧shu’ju
- 优先级队列
- 依赖服务的刷数据队列
- 数据同步服务可以在闲时进行处理
- 高优先级队列
- 数据同步服务会尽快处理
- 依赖服务的刷数据队列
优化
多线程提高吞吐量
- 数据同步服务在监听 mq 后,定时多线程从依赖服务的批量查询接口获取数据
- 一次批量查询不要太多,避免数据包过大
- 数据聚合服务在监听 mq 后,按照一个线程一个维度进行处理
- 通过 mget 方式从缓存中获取数据
- 数据同步服务在监听 mq 后,定时多线程从依赖服务的批量查询接口获取数据
mget 优化
- 避免 mget 批量获取数据时,走多次网络请求,连接多个redis实例才能获取到所有数据
- 所以在设置的时候通过 hash_tag 将数据路由到同一个 redis 实例上
- redis cluster 通过
{}
进行 hash_tag 设置,只要{}
之间的内容一致即可 - twemproxy 需要在配置文件中配置
hash_tag: "::"
,这样就可以通过::
进行 hash_tag 配置- 可以自定义配置样式
- redis cluster 通过
分段加载
- 在 数据同步服务或者数据聚合服务中,可以对数据进行分段存储,避免单个数据过大
链路降级
- nginx 应用服务器决定
- nginx 应用服务器读取本地缓存,没有的话读取缓存从集群
- nginx 应用服务器对缓存从集群进行计数,后者一段时间内无响应次数达到阈值,设置 flag 和 重试周期,重试周期内降级到数据直连服务,重试周期结束后尝试连接缓存从集群
- nginx 应用服务器同样对数据直连服务进行计数
- 数据直连服务走本地缓存+缓存主集群
- 降级会走依赖服务(读取 db 数据)自行聚合数据,依赖服务本身会设置到本地缓存+缓存主集群(会同步到缓存从集群中)中
- 上述服务各自也需要要做好 hystrix 限流和降级,nginx 一旦获得响应后,就会设置到本地缓存
lvs+keepalive
- todo