1. 消息队列
1.1 优缺点
优点/使用场景:
- 解耦。生产消息后直接给MQ,不用关心其他事务,监听返回消息就行。
- 异步。异步执行,提高吞吐量。发送者将消息给MQ后,不需要同步等待处理完毕,而是可以进行其它操作。
- 削峰。请求放在MQ里,Server根据处理能力处理消息,缓解服务器压力,不至于GG。
缺点:
- 系统可用性降低。MQ挂了,整个系统通信GG。
- 系统复杂度增加。加入MQ,引出一致性、传输可靠性、消息不被重复消费等等问题。
- 数据一致性问题。A处理结束返回,BC写库成功,D失败,数据不一致。
1.2 消息中间件
答:主要是ActiveMQ、RabbitMQ、RocketMQ和KafKa。
- ActiveMQ:老技术,现在用得不多。主从架构。
- RabbitMQ:开源,中小型用这个。主从架构。
- RocketMQ:阿里开发,和Dubbo RPC框架很像。分布式架构。
- Kafaka:专门做大数据。分布式架构。
1.3 常见问题
1.3.1 重复消费
因为网络问题导致Customer收到两条一样的消息,或者是消费模块处理失败请求重发消息。
解决方法
保证幂等性,即不管多少重复消息,最后处理结果还是一样。分为强校验和弱检验。
- 强校验:把多个流程放在一个事务,成功一起成功失败一起失败。通过唯一编号标识消息或者日志表记录去重。
- 弱检验:不重要的场景就用 id + 场景号放在redis中,有效时间内用redis判断。
1.3.2 顺序消费
因为延迟等原因,使得消息消费顺序和发送顺序不同。
解决方法
- 保证生产者-MQ-消费者,一一对应,消费成功一个再发下一个。
- 缺陷问题:吞吐量不够;耦合度太高。从业务层面保证消息顺序。
1.4 分布式事务
1.4.1 两段式提交
答:2pc两段式提交,最基础的模型。通过消息中间件协调多个系统,等每个系统事务都锁定了资源,通知中间件,中间件按顺序通知系统提交事务。
- 缺陷:A事务提交成功,B事务提交失败导致B事务一直锁定资源。
1.4.2 最终一致性
- 业务主动方本地事务提交失败,被动接收方不会收到消息的投递;
- 只要业务主动方本地事务执行成功,那么消息服务一定会投递消息给下游的业务被动方,并最终保证业务被动方一定能成功消费该消息(消费成功或失败,即最终一定会有一个最终态)。