大家好,我是飘渺~~

这篇文章我准备来聊一聊RocketMQ消息的一生。

不知你是否跟我一样,在使用RocketMQ的时候也有很多的疑惑:

  • 消息是如何发送的,队列是如何选择的?
  • 消息是如何存储的,是如何保证读写的高性能?
  • RocketMQ是如何实现消息的快速查找的?
  • RocketMQ是如何实现高可用的?
  • 消息是在什么时候会被清除?
  • ...

本文就通过探讨上述问题来探秘消息在RocketMQ中短暂而又精彩的一生。

核心概念

  • NameServer:可以理解为是一个注册中心,主要是用来保存topic路由信息,管理Broker。在NameServer的集群中,NameServer与NameServer之间是没有任何通信的。

  • Broker:核心的一个角色,主要是用来保存消息的,在启动时会向NameServer进行注册。Broker实例可以有很多个,相同的BrokerName可以称为一个Broker组,每个Broker组只保存一部分消息。

  • topic:可以理解为一个消息的集合的名字,一个topic可以分布在不同的Broker组下。

  • 队列(queue):一个topic可以有很多队列,默认是一个topic在同一个Broker组中是4个。如果一个topic现在在2个Broker组中,那么就有可能有8个队列。

  • 生产者:生产消息的一方就是生产者

  • 生产者组:一个生产者组可以有很多生产者,只需要在创建生产者的时候指定生产者组,那么这个生产者就在那个生产者组

  • 消费者:用来消费生产者消息的一方

  • 消费者组:跟生产者一样,每个消费者都有所在的消费者组,一个消费者组可以有很多的消费者,不同的消费者组消费消息是互不影响的。

消息诞生与发送

我们都知道,消息是由业务系统在运行过程产生的,当我们的业务系统产生了消息,我们就可以调用RocketMQ提供的API向RocketMQ发送消息,就像下面这样

consumer.registerMessageListener(newMessageListenerOrderly(){@OverridepublicConsumeOrderlyStatusconsumeMessage(List<MessageExt>msgs,ConsumeOrderlyContextcontext){//按照顺序消费消息记录returnnull;}});

消息清理

由于消息是存磁盘的,但是磁盘空间是有限的,所以对于磁盘上的消息是需要清理的。

当出现以下几种情况下时就会触发消息清理:

  • 手动执行删除
  • 默认每天凌晨4点会自动清理过期的文件
  • 当磁盘空间占用率默认达到75%之后,会自动清理过期文件
  • 当磁盘空间占用率默认达到85%之后,无论这个文件是否过期,都会被清理掉

上述过期的文件是指文件最后一次修改的时间超过72小时(默认情况下),当然如果你的老板非常有钱,服务器的磁盘空间非常大,可以将这个过期时间修改的更长一点。

有的小伙伴肯定会有疑问,如果消息没有被消息,那么会被清理么?

答案是会被清理的,因为清理消息是直接删除CommitLog文件,所以只要达到上面的条件就会直接删除CommitLog文件,无论文件内的消息是否被消费过。

当消息被清理完之后,消息也就结束了它精彩的一生。

消息的一生总结

为了更好地理解本文,这里再来总结一下RokcetMQ消息一生的各个环节。

消息发送
  • 生产者产生消息
  • 生产者在发送消息之前会拉取topic的路由信息
  • 根据队列选择算法,从topic众多的队列中选择一个队列
  • 跟队列所在的Broker机器建立网络连接,将消息发送到Broker上
消息存储
  • Broker接收到生产者的消息将消息存到CommitLog中
  • 在CosumeQueue中存储这条消息在CommitLog中的位置

由于CommitLog和CosumeQueue都涉及到磁盘文件的读写操作,为了提高读写效率,RokcetMQ使用到了零拷贝技术,其实就是调用了一下Java提供的api。。

高可用

如果是集群模式,那么消息会被同步到从节点,从节点会将消息存到自己的CommitLog文件中。这样就算主节点挂了,从节点仍然可以对外提供访问。

消息消费
  • 消费者会拉取订阅的Topic的路由信息,根据集群消费或者广播消费的模式来选择需要拉取消息的队列
  • 与队列所在的机器建立连接,向Broker发送拉取消息的请求
  • Broker在接收到请求知道,找到队列对应的ConsumeQueue,然后计算出拉取消息的位置,再解析出消息在CommitLog中的位置
  • 根据解析出的位置,从CommitLog中读出消息的内容返回给消费者
消息清理

由于消息是存在磁盘的,而磁盘的空间是有限的,所以RocketMQ会根据一些条件去清理CommitLog文件。

本篇文章来源于微信公众号: JAVA日知录



微信扫描下方的二维码阅读本文

此作者没有提供个人介绍
最后更新于 2024-08-01