RocketMQ生产者是如何发送消息的
首先先认识一下MessageQueue是什么
在创建Topic的时候,就需要指定一下这个topic需要对应多少个队列,也就是多少个MessageQueue,那么Topic、broker、MessageQueue之间有什么关系呢,可以举个例子来说明;假设现在有一个topic,然后指定了4个MessageQueue。我们都知道每个Topic都是分布式存储在多个Broker中的,如下图所示:
image.png
那么现在就有一个问题来了,如何决定一个Topic中的那些数据存放在这个Broker上,那些数据存放在另一个Broker上。为了解决该问题,此时RocketMQ就引入了一个MessageQueue的概念,本质上就是数据分片的机制。在这个机制中假设你的Topic中有1万条数据,然后这个Topic中有4个MessageQueue(RocketMQ其实默认的queue数就是4个)那么大概就可以理解为,每个MeaageQueue就存放了2500条数据。当然这个不是绝对的,有可能有的MeaageQueue的数据量多,有的少,这个根据你写入MessageQueue的策略决定。假设我们是平均分配数据,这样的话,就有可能把这数据分别放到两个Broker上,然后每个Broker上有两个MessageQueue,如下图:
image.png
所以其实MessageQueue就是RocketMQ中非常关键的一个数据分片机制,它通过MessageQueue将一个topic的数据拆分成很多个数据片,然后在每个Broker机器上存储一些MessageQueue。通过这个方式,就可以实现Topic数据的分布式存储。
生产者发送消息的时候是如何决定写入那个MessageQueue
生产者会和NameServer进行通信获取Topci的路由数据,所以生产者从NameServer就能知道这个Topic有几个MessageQueue,那些MessageQueue在哪台Broker上,那些MessageQueue在另一个Broker上,这些都知道的。
image.png
如果某个Broker出现故障该怎么办
如果某个Master Broker挂了,此时正在等待的其他Slave Broker自动热切换为Master Broker,那么这个时候这一组Broker 就可写入的Master Broker了。那么如果还按照之前的均匀的写入数据时,就会导致在一段时间内,每次访问挂掉的这个Master Broker都会访问失败,对于这个问题,是开启一个开关,sendLatencyFaultEnable
producer.setSendLatencyFaultEnable(true);
它的意思就是:某次访问一个Broker发现网络延迟有500ms,然后无法访问,那么就会自动回避访问这个broker一段时间,比如接下来3000ms内就不会访问这个broker了。这样的话就避免了一个Broker故障之后,短时间内生产者频繁的发消息到这个故障的Broker上,从而出现较多次的异常,而是在一个Broker故障之后,自动回避一段时间,过段时间再去访问它。过段时间Slave Broker就可能自动切换成Master Broker了,就可以访问它了。