高并发组件了解
消息队列
解耦
A服务和多个服务耦合,内部维护对多个服务发送数据的接口,那么这些接口如果有的挂了,有的不需要了,那么还得修改A内部的代码,如果使用MQ,A发送消息就好,不必考虑那么多事情。
通过一个 MQ,Pub/Sub 发布订阅消息这么一个模型,A 系统就跟其它系统彻底解耦了
异步
不需等待整个业务流程走完,把业务需要走的流程发送到MQ,其他服务进行消费走完接下来的流程即可
削峰
对短时间的大量请求进行队列内的消息堆积,等待服务进行能力范围内的消费
高可用(RabbitMQ)
三种模式:单机,普通集群,镜像集群
单机:玩具
普通集群:多个机器,创建的队列只会存放在一个实例上,其他实例还得拉取数据,造成了集群内部的大量流量消耗,而且队列所在节点宕机,数据就丢了,做不到高可用,但是吞吐量会高一点
镜像集群:创建的队列就会存放在多个实例上,每次写消息都会同步到所有实例 。 缺点:没有扩展性(queue多了,加机器也没用,因为每个机器上都有完整的数据),性能开销大
Kafka(天然分布式)
每个机器放一部分数据,每个节点内的数据都会有副本,同步到其他机器上,然后选举出一个leader,生产和消费都和他打交道
生产和消费都在所有的follower同步好返回ack之后消息队列才返回操作成功
如何保证消息不被重复消费/如何保证消息消费的幂等性
原因:kafka为例:一条消息消费后会提交offset,下一次消费会从offset后面的数据进行消费,如果消费者进程重启,那么消费过的offset就没有上交,就会导致重复消费
重复消费不可怕,可怕的是没考虑到重复消费之后,怎么保证幂等性。
生产者发送数据时,加一个全局唯一的id,消费时查一下redis是否消费过
如何保证消息的可靠性传输/如何处理消息丢失的问题
RabbitMQ
生产者弄丢了数据
解决方案:1. 事务机制(耗性能,因为是同步)2. confirm机制(性能号,异步),生产者开启confirm模式,发送的消息分配一个唯一的id,如果送达rabbitmq,会回传一个ack消息,如果送达失败,则会回调一个nack接口,告知接受失败
消息队列弄丢了数据
解决方案:消息队列进行持久化:1. 创建队列时进行持久化。2. 发送消息时吧参数设置为持久化
但是消息队列还没进行持久化就挂了咋办:结合confirm,持久化成功之后再返回ack,如果没有持久化那么生产者是可以进行重发的。
消费者弄丢了数据