消息队列可以用来解决什么问题

33 阅读3分钟

消息队列可以用来解决什么问题

异步、削峰、解耦。消息队列的应用场景都是围绕这三点设计的,如日志处理、消息通讯。

案例

秒杀场景

  • 秒杀场景在消息队列之前,要先做用户校验,用户是否参加过秒杀了。
  • 然后是扣库存,库存扣除成功才是抢到。
  • 再把请求丢到消息队列里,后续异步创建订单和支付

这个设计把秒杀分为两轻重两部分

  • 消息队列之前是轻量级操作,瓶颈是Redis性能
  • 消息队列之后是重量级操作,校验交易合法性、操作数据库

介绍

  • 消息队列经常用在秒杀场景。秒杀请求进来后会有一个轻量级服务做限流、校验、扣库存操作,都是内存操作,扣库存成功后丢到消息队列。
  • 订单服务再把请求拿出来,创建真正的订单,并提醒用户支付。这部分是重量级操作,无法支撑大规模并发。

订单超时取消

  • 可以通过消息队列的延时消息实现

介绍

  • 消息队列也用在订单超时取消场景。可以准备一个延时队列,超时时间30分钟就是延时30分钟
  • 要注意并发问题:30分钟这一刻,用户支付的同时消费者超时消息就会造成并发问题,可以使用乐观锁等。

亮点

为什么一定要使用消息队列?

本质上在问不异步、不削峰、不解耦会有什么问题?

性能差、扩展性差、可用性差

性能差

  • 要等所有调用全部返回后才返回响应
  • 即使使用多线程并发调用也比消息队列差
  • 即使可以接受并发调用的损坏,也不能解决扩展性差和可用性差

扩展性

  • 消息队列新的下游进来只要订阅消息即可,不用关心其他的
  • 非消息队列可能需要上游下游同步联调,人员和时间都是浪费

也可以通过一致性的抽象来实现扩展性问题,提供一套对接规范,包括API定义、请求和响应中的字段含义等

可用性

  • 消息队列只要确保自己把消息发送到消息队列上就操作成功了
  • 同步方案中要保证下游都成功才算成功

事件驱动

组件1发送一个消息到消息队列,组件2消费这个消息,消费后组件2发送一个消息到消息队列,然后组件3消费

优点

耦合性低、可扩展性、高可用

和SAGA分布式事务结合

  • 当某个步骤完成后,会发出一个或多个时间,驱动事务中的后续步骤。
  • 包括回滚也是这样,比如发出一个代表一个步骤执行失败的时间,对应的消费者就会执行反向补偿步骤
介绍
  • 用事件驱动实现了SAGA的分布式事务解决方案
  • 基于事件驱动的SAGA模式在每一个步骤结束后发送最少一个事件。消费者消费后再执行下个步骤
  • 比如更新DB再更新缓存的场景就可以使用