以巧克力工厂类比,工厂三个操作环节磨粉,做酱,凝固;

使用传送带可提高(通信)效率;

使用仓储存储半成品可解决(通信缓存)传送带物品无人接收;

一、异步处理

> 对于一个电商秒杀请求,如下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. 产生的数据不一致问题