消息队列可以用来解决什么问题
异步、削峰、解耦。消息队列的应用场景都是围绕这三点设计的,如日志处理、消息通讯。
案例
秒杀场景
- 秒杀场景在消息队列之前,要先做用户校验,用户是否参加过秒杀了。
- 然后是扣库存,库存扣除成功才是抢到。
- 再把请求丢到消息队列里,后续异步创建订单和支付
这个设计把秒杀分为两轻重两部分
- 消息队列之前是轻量级操作,瓶颈是Redis性能
- 消息队列之后是重量级操作,校验交易合法性、操作数据库
介绍
- 消息队列经常用在秒杀场景。秒杀请求进来后会有一个轻量级服务做限流、校验、扣库存操作,都是内存操作,扣库存成功后丢到消息队列。
- 订单服务再把请求拿出来,创建真正的订单,并提醒用户支付。这部分是重量级操作,无法支撑大规模并发。
订单超时取消
- 可以通过消息队列的延时消息实现
介绍
- 消息队列也用在订单超时取消场景。可以准备一个延时队列,超时时间30分钟就是延时30分钟
- 要注意并发问题:30分钟这一刻,用户支付的同时消费者超时消息就会造成并发问题,可以使用乐观锁等。
亮点
为什么一定要使用消息队列?
本质上在问不异步、不削峰、不解耦会有什么问题?
性能差、扩展性差、可用性差
性能差
- 要等所有调用全部返回后才返回响应
- 即使使用多线程并发调用也比消息队列差
- 即使可以接受并发调用的损坏,也不能解决扩展性差和可用性差
扩展性
- 消息队列新的下游进来只要订阅消息即可,不用关心其他的
- 非消息队列可能需要上游下游同步联调,人员和时间都是浪费
也可以通过一致性的抽象来实现扩展性问题,提供一套对接规范,包括API定义、请求和响应中的字段含义等
可用性
- 消息队列只要确保自己把消息发送到消息队列上就操作成功了
- 同步方案中要保证下游都成功才算成功
事件驱动
组件1发送一个消息到消息队列,组件2消费这个消息,消费后组件2发送一个消息到消息队列,然后组件3消费
优点
耦合性低、可扩展性、高可用
和SAGA分布式事务结合
- 当某个步骤完成后,会发出一个或多个时间,驱动事务中的后续步骤。
- 包括回滚也是这样,比如发出一个代表一个步骤执行失败的时间,对应的消费者就会执行反向补偿步骤
介绍
- 用事件驱动实现了SAGA的分布式事务解决方案
- 基于事件驱动的SAGA模式在每一个步骤结束后发送最少一个事件。消费者消费后再执行下个步骤
- 比如更新DB再更新缓存的场景就可以使用