消息队列面试随笔

消息队列:activemq,rabbitmq,rocketmq,kafka

为什么使用消息队列?

解耦,异步,削峰

使用消息队列的优缺点

优点:解耦,异步,削峰
缺点:
1降级系统可用性(如果mq挂了,整套系统就崩溃了)
2系统复杂性提高(怎么保证不重复消费,怎么处理消息丢失,怎么保证消息传递顺序性等)
3一致性(bcd系统中,d系统写库失败,数据就不一致了)

四种消息队列都各有什么优缺点

activemq,rabbitmq万级吞吐量较低,rocketmq,kafka十万级吞吐量,其中kafka最大的优点就是吞吐量适用于大数据
rocketmq的topic可以达到几百几千个对吞吐量影响不大这是rm的优势,kafka到几百个时吞吐量明显下降,需要增加更多机器资源
rabbitmq社区不太活跃但稳定,rm社区相对活跃,中小公司没有自主维护mq能力建议使用rabbitmq,有自主维护能力的建议使用rocketmq,大数据建议使用kafka
rabbitmq有一个ui界面操作方便

如何保证消息队列的高可用性

rabbitmq保证高可用
单机模式,普通集群模式,镜像集群模式
单机模式:demo
1.普通集群模式:不是高可用的,其他服务器只存queue的元数据相当于key,只有一台服务器存真实数据,消费者若是从其他服务器取数据,会先向存真实数据的服务器拉数据再拿到数据,缺点:前者拉数据的开销,后者单实例性能瓶颈,若放queue的实例宕机了,就无法拉取,若开启消息持久化,消息不一定会丢但必须等到这个实例恢复才能拉取消息所以无高可用性。这种方案书钥匙提高吞吐量,让集群中多个节点来服务某个queue的读写操作。
2.镜像集群模式:高可用,每个服务器都有queue数据,缺点网络带宽压力和消耗很重,没有扩展性可言。

 

kafka保证高可用如何保证消息不被重复消费(怎么保证消息幂等性)

一个数据或一个请求,重复来多次怎么确保对应的数据不会改变

1.根据主键查一下,如果这数据有了,就别插入了,update一下。
2.写redis,每次都是set,天然幂等性
3.让生产者发送每条数据的时候加一个全局唯一的id,在消费的时候,先根据这个id去查。
4.设置数据状态,每次请求都判断成功失败进行冲正处理,用户交易进行秒控制不可再操作等
(保证消息幂等性需要结合业务)

 

如何保证消息不丢失

rabbitmq:

从生产者角度

1.rabbitmq可以开启提供的事务,但缺点是耗性能,吞吐量会下来。

2.开启confirm模式,channel.confirm,发送一个消息就不用管了,rm会自动回调定义的接口。

从rabbitmq本身

1.rabbitmq本身也有几率丢失消息,开启持久化,但需要注意的是仍有极小概率数据丢失,即rm保存在内存中的数据还未持久化就宕机导致数据丢失。

rm持久化有两步

-创建queue 时持久化,保证rm持久化queue元数据。

-发送消息的时候将消息的deliveryMode设置为2,将消息设置为持久化的。

必须要同时设置这两个持久化,当rabbitmq挂了也能恢复queue元数据及里面的数据。

从消费者本身

1关闭rabbitmq的autoack,然后在执行完业务后再ack

kafka

从消费者本身

1.关闭自动的offset,每次处理完业务手动offset。

此处的问题是当处理完业务还未来的及offset时宕机了,会导致重复消费,所以要确保数据幂等性。

kafka本身弄丢数据

kafka某个broker宕机,然后重新选举partiton的leader时。要是此时其他的follower刚好还有些数据没有同步,结果此时leader挂了,然后选举某个follower成leader之后,就少了一些数据。

1.给这个topic设置replication.factor参数:这个值必须大于1,要求每个partition必须有至少2个副本

2.在kafka服务端设置min.insync.replicas参数:这个值必须大于1,这个是要求一个leader至少感知到有至少一个follower还跟自己保持联系,没掉队,这样才能确保leader挂了还有一个follower吧

3.在producer端设置acks=all:这个是要求每条数据,必须是写入所有replica之后,才能认为是写成功了

4.在producer端设置retries=MAX(很大很大很大的一个值,无限次重试的意思):这个是要求一旦写入失败,就无限重试,卡在这里了

生产者

如果按照上述操作设置了ack=all就不会丢失数据,要求是leader接收到消息,所有的follower都同步到了消息之后,才认为本次写成功了。如果没满足这个条件,生产者会自动不断的重试,重试无限次。

如何解决mq积压问题

1)先修复consumer的问题,确保其恢复消费速度,然后将现有consumer都停掉

2)新建一个topic,partition是原来的10倍,临时建立好原先10倍或者20倍的queue数量

3)然后写一个临时的分发数据的consumer程序,这个程序部署上去消费积压的数据,消费之后不做耗时的处理,直接均匀轮询写入临时建立好的10倍数量的queue

4)接着临时征用10倍的机器来部署consumer,每一批consumer消费一个临时queue的数据

然后再恢复原有的consumer。

 

如何解决消息队列的延时以及过期失效问题

rabbitmq是可以设置消息延时失效的,正常情况下生产是不设置失效的。如果设置了,并延时失效了,就需要写一个临时的程序去查出失效的数据。

 

如何解决mq磁盘空间满了

消费一个丢一个,快速释放资源,然后再写一个临时程序去查失效的数据。

 

rabbitmq空时可以看一下

https://blog.csdn.net/Anumbrella/article/details/79920854

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值