消息队列的主要使用场景:解耦、异步、削峰
解耦:一个系统或者一个模块调用多个系统时,互相之间的调用复杂,维护麻烦,不需要同步进行的接口可以借用MQ异步解耦
异步:不需要同步的数据借用MQ异步处理,减少接口调用时间
削峰:高峰期请求先打入MQ,mysql每秒处理数2000。
消息队列缺点
(1):系统可用性降低
(2):系统复杂度提高
(3):一致性问题
如何保证消息不被重复消费
重复消费场景:处理失败导致重发消息,多线程下会造成多次重发。
采用幂等处理
幂等性:一个数据,或者一个请求,给你重复来多次,你得确保对应的数据是不会改变的,不能出错。
分为强校验和弱校验
强校验:比较重要的数据处理使用强校验,调用接口使用唯一标识,如果流水表有记录就不处理,没有就进行处理。
弱校验:唯一标识丢入redis缓存,有就处理,没有就不处理。
分布式事务
事务:事务就是一系列操作,要么同时成功,要么同时失败。然后会从事务的 ACID 特性(原子性、一致性、隔离性、持久性)展开叙述。
分布式事务大概分为:
(1):2pc(两段式提交)
(2):3pc(三段式提交)
(3):TCC(Try、Confirm、Cancel)
(4):最大努力通知
(5):XA
(6):本地消息表(ebay研发出的)
(7):半消息/最终一致性(RocketMQ)
如何保证消息不丢失
保证消息的可靠性需要三方配合。生产者
需要处理好Broker
的响应,出错情况下利用重试、报警等手段、Broker
需要控制响应的时机,单机情况下是消息刷盘后返回响应,集群多副本情况下,即发送至两个副本及以上的情况下再返回响应、消费者
需要在执行完真正的业务逻辑之后再返回响应给Broker
。
保证消息的顺序性
拆分多个 queue,每个 queue 一个 consumer,就是多一些 queue 而已,确实是麻烦点;或者就一个 queue 但是对应一个 consumer,然后这个 consumer 内部用内存队列做排队,然后分发给底层不同的 worker 来处理。