解耦:消息队列

解耦:消息队列

业务场景

消息队列是重要的分布式系统组件,在高性能、高可用、低耦合等系统架构中扮演着重要作用。可用于异步通信、削峰填谷、解耦系统、数据缓存等多种业务场景。

常用的消息队列实现有:Kafka、RabbitMQ、RocketMQ、Pulsar、ActiveMQ 等等。关于消息队列选型可参考:《【万字长文】消息队列(MQ)选型及常见问题看这一篇就够了》本节将主要介绍如何使用消息队列去解决业务上的具体问题。

打个小广告:《一篇文搞定消息队列选型》

案例

⓵ 解耦系统

以电商系 IT 架构为例。在传统的紧耦架构中,客户下单后,订单系统收到请求后,调用库存系统减库存。这种模式有如下缺点:

  • 订单系统与库存系统强耦合,可能是服务内 RPC 调用;
  • 遇到突发流量时,库存系统负载(查询、修改)。

引用 MQ 后的方案:

引入 MQ 后,订单系统和库存系统分别工作,解除了强耦合性。即便在下单时库存系统宕机了,也不影响正常下单(待库存系统恢复后,从 MQ 取出订单保证最终成功)。

电商网站中,新的用户注册时,需要将用户的信息保存到数据库中,同时还需要额外发送注册的邮件通知、以及短信注册码给用户。

⓶ 异步通信

电商网站中,新的用户注册时,需要将用户的信息保存到数据库中,同时还需要额外发送注册的邮件通知、以及短信注册码给用户。

传统的做法有两种:串行的方式、并行的方式。

串行的方式:

将注册信息写入数据库后,先发送邮件通知,再发送短信提醒。以上三个任务全部完成后,返回给客户端。

图:串行发送

并行的方式:

将注册信息写入数据库成功后,发送注册邮件的同时,发送注册短信。以上三个过程完成后,返回给客户端。与串行的差别是并行的方式可以缩短处理时间。

图:并行发送

消息队列:

引入消息队列后,非关键路径(通知部分)就可以异步处理了,从而实现快速响应:

  • 注册信息写入数据库成功后,再把发送注册邮件、注册短信的消息写入消息队列,返回给客户端;
  • 然后,服务端订阅消息队列(保证最终成功),分别发送注册邮件、注册短信。

⓷ 削峰填谷

像双十一、手机预约抢购等对 IO 时延敏感的业务场景,当外部请求超过系统负载时,如果系统没有过载保护策略,很可能会被短时的峰值流量冲垮。

针对这种洪峰流量,引入消息队列,将非即时处理的业务逻辑进行异步化,处理成功后通知用户(邮件、短信等)。这种削弱峰值流量延缓处理的方式,相当于给系统做了一层缓冲。

图:削峰填谷

上图中,黄色的部分代表超出消息处理能力的部分。把黄色部分的消息平均到之后的空闲时间去处理,这样既可以保证系统负载处在一个稳定的水位,又可以尽可能地处理更多消息。通过配置流控规则,可以达到消息匀速处理的效果。

⓸ 广播

假如,客户购买商品后,子系统会有以下动作:

  • 积分系统累积成长积分;
  • 赠品系统给客户发赠品;
  • 推荐系统推送商品周边;

凡此种种,这些子系统之间没有依赖关系。引入 MQ 可以大大简化业务逻辑:

  • 降低交易系统的复杂度,仅生产交易消息;
  • 解除系统间依赖,生产一次数据,可被不同子系统同时消费,多次复用;
  • 可以根据业务特性,延迟处理。

⓹ 延时队列

消息队列可以实现一些延时操作,如定时调度、超时处理等。

分布式定时调度:

在需要精细化调度的场景中,如每 2 分钟触发一次消息推送。传统基于数据库的定时调度方案在分布式场景下(特别是数据量大的时候),性能不高,实现复杂。基于消息队列(如 RocketMQ)可以封装出类似的定时触发器:

任务超时处理:

以购买火车票为例,我们在 12306 下单后暂未支付,订单是不会被取消的。而是等待一段时间后(如 30 min),系统才会关闭未支付的订单。可以使用消息队列实现超时任务检查:

基于定时消息的超时任务处理有如下优势:

  • 精度高、开发门槛低:基于消息通知方式不存在定时阶梯间隔。可以轻松实现任意精度事件触发,无需业务去重。
  • 高性能可扩展:传统的数据库扫描方式较为复杂,需要频繁调用接口扫描,容易产生性能瓶颈。消息队列具有高并发和水平扩展的能力。

其他:

延迟消息的使用场景很多,比如异常检测重试、订单超时取消等,例如:

  • 服务请求异常,需要将异常请求放到单独的队列,隔 5 分钟后进行重试;
  • 用户购买商品,但一直处于未支付状态,需要定期提醒用户支付,超时则关闭订单;
  • 面试或者会议预约,在面试或者会议开始前半小时,发送通知再次提醒。

小结

谚云:All problems in computer science can be solved by another level of indirection.

计算机科学中的所有问题都可以通过另一个中间层来解决。

0%