消息模型
消息模型
RocketMq、JMQ模型分别为Broker、Topic、Queue。
Kafka:将Queue换成Partition。
消费者、MQ、生产者关系图
假设有一个主题 MyTopic,我们为主题创建 5 个队列,分布到 2 个 Broker 中。
假设我们有 3 个生产者实例:Produer0,Produer1 和 Producer2。
这 3 个生产者是如何对应到 2 个 Broker 的,又是如何对应到 5 个队列的呢?这个很简单,不用对应,随便发。每个生产者可以在 5 个队列中轮询发送,也可以随机选一个队列发送,或者只往某个队列发送,这些都可以。比如 Producer0 要发 5 条消息,可以都发到队列 Q0 里面,也可以 5 个队列每个队列发一条。
消费组、消费者和队列的对应关系
每个消费组(其实就是业务应用)就是一份订阅,它要消费主题 MyTopic 下,所有队列的全部消息。注意,队列里的消息并不是消费掉就没有了,这里的“消费”,只是去队列里面读了消息,并没有删除,消费完这条消息还是在队列里面。
多个消费组在消费同一个主题时,消费组之间是互不影响的。比如我们有 2 个消费组:G0 和 G1。G0 消费了哪些消息,G1 是不知道的,也不用知道。G0 消费过的消息,G1 还可以消费。即使 G0 积压了很多消息,对 G1 来说也没有任何影响。
然后我们再说消费组的内部,一个消费组中可以包含多个消费者的实例。比如说消费组 G1,包含了 2 个消费者 C0 和 C1,那这 2 个消费者又是怎么和主题 MyTopic 的 5 个队列对应的呢?
由于消费确认机制的限制,这里面有一个原则是,在同一个消费组里面,每个队列只能被一个消费者实例占用。至于如何分配,这里面有很多策略。总之保证每个队列分配一个消费者就行了。比如,我们可以让消费者 C0 消费 Q0,Q1 和 Q2,C1 消费 Q3 和 Q4,如果 C0 宕机了,会触发重新分配,这时候 C1 同时消费全部 5 个队列。
再强调一下,队列占用只是针对消费组内部来说的,对于其他的消费组来说是没有影响的。比如队列 Q2 被消费组 G1 的消费者 C1 占用了,对于消费组 G2 来说,是完全没有影响的,G2 也可以分配它的消费者来占用和消费队列 Q2。
最后说一下消费位置,每个消费组内部维护自己的一组消费位置,每个队列对应一个消费位置。消费位置在服务端保存,并且,消费位置和消费者是没有关系的。每个消费位置一般就是一个整数,记录这个消费组中,这个队列消费到哪个位置了,这个位置之前的消息都成功消费了,之后的消息都没有消费或者正在消费。
你可以看到,这个表格中并没有消费者这一列,也就是说消费者和消费位置是没有关系的。