常见消息队列分析对比

消息队列

应用场景

  • 应用解耦,比如,用户下单后,订单系统需要通知库存系统,假如库存系统无法访问,则订单减库存将失败,从而导致订单失败。订单系统与库存系统耦合,这个时候如果使用消息队列,可以返回给用户成功,先把消息持久化,等库存系统恢复后,就可以正常消费减去库存了。
  • 削峰填谷,比如,秒杀活动,一般会因为流量过大,从而导致流量暴增,应用挂掉,这个时候加上消息队列,服务器接收到用户的请求后,首先写入消息队列,假如消息队列长度超过最大数量,则直接抛弃用户请求或跳转到错误页面。
  • 日志系统,比如,客户端负责将日志采集,然后定时写入消息队列,消息队列再统一将日志数据存储和转发。

1.Kafaka、RabbitMQ、RocketMQ之间的区别是什么?

  • 性能:消息中间件的性能主要衡量吞吐量
    • RabbitMQ单机QPS在万级别
    • Kafaka单机QPS能够达到百万级别
    • RocketMQ单机写入TPS单实例约7万条/秒,单机部署3各Broker,可以跑到最高12万条/秒,消息大小10个字节。
  • 数据可靠性:Kafaka与RabbitMQ都具备多副本机制,数据可靠性较高,RocketMQ支持实时异步刷盘,同步刷盘,同步Replication,异步Replication。
  • 服务可用性:Kafaka采用集群部署,分区与多副本的设计,使得单节点宕机对服务无影响,且支持消息容量的线性提升。RabbitMQ支持集群部署,集群节点数量有多种规格。RocketMQ是分布式架构,高可用。

2.Kafaka的架构

  • kafaka的架构包括3个角色:
    • 生产者(Producer):消息和数据的生产者。
    • 代理(Broker):缓存代理,Kafaka的核心功能。
    • 消费者(Consumer):消息和数据消费者。
  • Kafaka给Producer和Consumer提供注册的接口,数据从Producer发送到Broker,Broker承担一个中间件缓存和分发的作用,负责分发注册到系统中的Consumer。
  • Kafaka数据保留策略:按照过期时间保留和按照存储的消息大小保留。

3.Kafaka怎么保证消息是有序的?

  • 消息在被迫追加到Partition(分区)的时候都会分配一个特定的偏移量(offset)。Kafaka通过偏移量(offset)来保证消息在分区内的顺序性。
    • 一个Topic只对应一个Partition
    • 发送消息的时候指定key/partition

4.Kafaka怎么保证消息不丢失?

  • 生产者丢失消息的情况:消息可能在发送的过程中由于网络问题导致消息没有发送成功。Kafaka生产者发送消息send实际上是异步操作,如何保证消息发送成功:
    • 通过调用get方法获取发送结果,但是这样就变为了同步操作影响性能。一般不推荐之间使用get方式,而是采用回调函数,在回调函数里检查失败原因在做重发。
    • 设置Producer的retries(重试次数)一个合理值,一般为3,但是为了保证消息不丢失可以设置的大一点,如此设置后,当出现网络原因消息没有发送成功会自动重发。还需要设置重发时间间隔,一般重试的间隔时间不要太短,时间太短重试的效果就不明显了。
  • 消费者丢失消息的情况:消费者拉到某个分区的消息后消费者会自动提交offset。这样就会产生一个问题,消费者自动提交offset后但是还没真正消费服务突然挂掉了,这种情况消息实际上是没有被消费的。所以只需要关闭消费者自动提交offset,在每次真正消费完成后在进行手动提交offset。这样又可能出现真正消费完成了但是手动提交offset失败了,就有可能导致消息重复消费。(可通过幂等处理)
  • Kafaka弄丢消息:在leader副本所在的broker突然挂掉的时候,那么就要从follower副本重新选出一个leader,但是leader还有一些数据没有被follower同步,就会造成消息丢失。解决方法是设置unclean.leader.election.enable=false,当leader副本发生故障的时候,就不会选择follower和leader同步程度达不到要求的副本作为新的leader,这样就降低了消息丢失的可能性。

5.Kafaka多副本机制

Kafaka分区中多个副本之间会有一个leader,其他副本称为follower,我们发送的消息会被发送到leader,然后follower才能从leader拉取消息进行同步。 生产者和消费者只与leader副本进行交互,其他副本存在只为了保证消息存储的安全性。当leader发生故障的时候会从follower中选出一个leader,如果follower中有和leader同步程度达不到要求的就不能参与leader竞选。

6.RabbitMQ

  • RabbitMQ有哪些角色
    • 生产者:消息的创建者,负责创建消息和推送消息到服务器。
    • 消费者:消息的接收方,用于处理消息和确认消息。
    • 代理:RabbitMQ本身,相当于扮演了“快递”角色。
  • RabbitMQ的重要组件
    • ConnectionFactory(连接管理器):应用程序与RabbitMQ服务器之间建立连接的管理器。
    • Channel(信道):消息推送的通道。
    • Exchange(交换机):用于接收和分配消息。
    • Queue(队列):用于存储生产者产生的消息。
    • RoutingKey(路由key):用于把生产者生成的数据分配到交换机上。
    • BindingKey(绑定key):用于把交换机的消息绑定到队列上。



7.RabbitMQ消息消费问题

  • 如何确保消息被消费
    • 关闭自动ack
    • 在接收到消息并处理完成后,使用channel.basicAck()进行手动消息确认。
  • 消费者接收到消息必须消费吗
    • 订阅者接收到消息后可以选择拒绝消费:channel.basicReject(id, true),mq会将消息分配给其他订阅者。
    • 设置死信队列,死信队列是专门用于存放被拒绝的消息队列。

8.RabbitMQ事务

  • 事务使用方式有三种,主要是针对信道的设置,如下:
    • 声明启动事务模式:channel.txSelect()
    • 提交事务:channel.txCommit()
    • 回滚事务:channel.txRollback()
  • 什么情况下事务无效:autoAck=true,开启自动消息确认的时候,事务是无效的。因为自动消费确认的时候,mq会直接把消息从队列中移除,即使有事务回滚也没用。

9.RabbitMQ如何保证消息不丢失?

  • 开启RabbitMQ事务(同步,性能差)
  • 开启confirm模式(异步,性能好)
    • MQ:Exchange持久化、queue持久化、消息持久化
    • 消费者:关闭自动ack
#Java##程序员#
全部评论

相关推荐

点赞 评论 收藏
分享
1.算法 合并链表还有个也是链表的top100忘记了2.自我介绍3.消息队列为了解决什么问题异步秒杀具体是一个怎么样的实现消费的时候发现没有库存怎么办为什么引入redis能不能在启动的时候把所有的信息都加载到服务内存而不用redis用过rabbitmq延时消费吗4.沾包问题根本原因ip层会沾包吗http会吗5.http常用的头字段6.websocket建立的过程和http的关系7.jwt和session后端服务有多个session怎么处理8.反问其实在正式开始找工作之前,从选择做java后端这个方向开始我就时不时会后悔,虽然当初看着java岗位多进来了,但是实际上看这几年的招聘情况是不甚乐观,也曾经想过要不要转前端或者go,但是因为自己的惰性和沉没成本没能狠下心去转。在这学期国庆终于把最基础的课程项目和简历做完之后就开始投了。说实话和我想象的完全不一样,我想着就是先投小厂实习一段时间再中厂,等暑期实习冲击大厂,可以就业形势远比我想象的要紧张,中小厂完全不回我简历或者是没有除了应届生以外的实习渠道,反而是那几家中大厂至少还能投(虽然大部分也是泡池子),这也就彻底改变了我的规划,决定all in中大厂,正如9本和普通本科的面试/投递率有千差万别,我相信有一段中大厂实习的背书肯定不会发生别人口中那种暑期实习泡池子的情况。在写下这期笔记的时候我也已经有自己的去处了,可能还会更新几个面经,但是说实话大头就要放在实际工作和准备暑期实习上了。腾讯,我们暑期实习见!
查看18道真题和解析
点赞 评论 收藏
分享
评论
2
14
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务