以巧克力工厂类比,工厂三个操作环节磨粉,做酱,凝固;
使用传送带可提高(通信)效率;
使用仓储存储半成品可解决(通信缓存)传送带物品无人接收;
一、异步处理
> 对于一个电商秒杀请求,如下5步操作
1. 风险控制
2. 锁库存
3. 出订单
4. 短信通知
5. 更新统计数据
APP => 网关 => 后端服务(5步[风控 => 库存 => 订单 => 短信 => 统计])
APP => 网关 => 后端服务(2步[风控 => 库存])——生产——> 消息队列 => 订单
=> 短信
=> 统计
前两步骤即可完成下单,因此可以直接返回秒杀结果,而后三步则通过消息队列去异步地并行完成。
优点:更快的秒杀响应;更好的资源调度(秒杀时处理请求,秒杀后处理异步任务);
二、流量控制
秒杀期间保护服务在不被流量压垮的情况下,尽可能多地处理更多请求(越少错误和超时越好)。即系统的健壮性设计。
使用消息队列隔离后端服务和网关,已达到流量控制。
APP => 网关 ==生产==> 消息队列 ==消费==> 秒杀服务
请求堆积在队列,下游服务尽力取出处理,这种架构可以方便的水平拓展下游服务以提升处理能力。
超时请求取出时直接丢弃,APP无响应直接处理秒杀失败。
架构优点:根据下游处理能力自动调节流量,达到"削峰填谷"的作用。但如此代价在于
1. 性能代价:增加了网关到服务调用链环节,延时加长;
2. 实现代价:网关到服务的同步调用,都要改为异步消息,增加了复杂度。(什么是系统复杂度?)
更简单一些的流量控制算法,令牌桶算法如下。
APP => 网关 => 秒杀服务
||(消费)
令牌发生器 ==生产==> 令牌队列
单位时间内放入固定数量令牌到令牌桶,网关请求进入增加从桶中获取令牌的过程,如果没获取到就拒绝请求。可控制单位时间内处理不超过固定数量的请求而达到流量控制。
令牌桶就是固定容量队列加令牌生成器,以固定速率放入。网关从队列获取令牌成功则处理请求,否则返回失败。
三、服务解耦
订单作为电商核心模块的数据,新订单创建后:
1. 支付sys需发起支付流程
2. 风控sys需审核订单合法性
3. 客服sys需短信通知用户
4. 经营分析sys需更新统计数据
每个订单下游系统都要实时获得订单数据。订单系统与诸多下游系统的交互接口,任何下游需要发生接口变更,订单都需开发上线。作为核心模块不可接受。模块耦合过于紧密导致的牵一发动全身的问题。
订单系统在发生订单数据变更时,放消息队列,系统下游实时消费订单数据解决。至此下游系统的变更时,订单系统无需随之变更。
小结
除了异步、解耦、流量控制。还能
1. 发布/订阅系统实现微服务级系统间的观察者模式(是什么?)
2. 链接流计算任务和数据(是什么?)
3. 消息广播
局限性
1. 引入队列带来的延迟
2. 带来的系统复杂度
3. 产生的数据不一致问题