RocketMQ的使用2
1、生产者组和消费者组
1.1、生产者组
通常具有同样属性(处理的消息种类-topic、以及消息处理逻辑流程—分布式多个客户端)的一些producer可以归为同一个group。生产者组的作用是在集群的情况下,一个生产者down之后,本地事务回滚后,可以继续联系该组下的另外一个生产者实例,不至于导致业务走不下去。
在事务消息机制中,如果发送某条消息的producer-A宕机,使得事务消息一直处于PREPARED状态并超时,则broker会回查同一个group的其他producer,确认这条消息应该commit 还是 rollback。
将发送不同主题的实例划分为同一个生产者组通常也是可行的,但也不是太建议,从规范管理和监控层面来讲也不太方便。
1.2、消费者组
消费者组是一组消费者的集合,这些消费者共同订阅一个或多个主题(Topic),并协同消费这些主题中的消息。每个消费者组都有一个唯一的标识符(Group ID),消息队列系统会根据这个标识符来区分不同的消费者组,并为每个消费者组独立维护消费进度。
特点说明:
- 默认情况下,在同一个消费者组里,一条消息只会被组内的一个消费者实例消费。消息队列系统会通过负载均衡算法将消息分配给消费者组内的不同实例。在 RocketMQ 中,同个消息主题会被划分为多个队列,RocketMQ 的 Broker 会感知到消费者组内的所有消费者实例,并根据负载均衡算法(如平均分配)将该主题下的消息队列分配给各个消费者实例,每个消息队列在同一时间只会被一个消费者实例消费,从而保证每条消息仅被一个实例处理。在一些特殊情况,比如消息模式是广播模式时,1个消息会被多个实例消费。
- 不同消费者组是互相独立的,可以订阅同个主题或不同主题。每个消费者组可以独立地消费主题中的消息。当生产者将消息发送到某个主题后,消息队列会为每个订阅了该主题的消费者组维护一个独立的消费进度,不同消费者组对消息的消费是相互隔离、互不影响的。
-
一条消息在不同消费者组中通常会被重复消费。消息队列系统对每个消费者组的消费进度是独立维护的。当生产者把消息发送到某个主题后,各个订阅了该主题的消费者组会各自记录自己消费到的位置。不同消费者组对消息的消费相互隔离,彼此不会影响。所以,每个消费者组都可以独立地从主题中获取消息并进行消费,同一条消息通常在不同消费者组中会被重复处理。
在同个消费者组内,不同的示例应保持完全一样的订阅规则(包括主题、Tag),非常不建议在同个消费者组内不同实例订阅不同规则。从技术实现角度来看,同个消费者组内的不同实例虽然能够订阅不同主题。但是,消费者组的设计初衷就是让组内的实例共同协作来消费同一个或多个主题的消息,以实现负载均衡、容错等功能。当组内实例订阅不同主题时,可能会存在以下问题:
- 消费进度管理混乱:消息队列系统通常会为每个消费者组维护统一的消费进度,当组内实例订阅不同主题时,消费进度的管理会变得复杂,容易出现消费进度不一致的问题,可能会漏掉一些消息。
- 负载均衡失效:消费者组的负载均衡机制是基于组内实例共同消费相同主题设计的,订阅不同主题会使该机制无法正常工作,可能导致部分实例负载过高,而部分实例闲置。
- 容错性降低:消费者组的容错机制依赖于组内实例对相同主题的共同消费,订阅不同主题会削弱这种容错能力,当某个实例出现故障时,无法保证消息的正常消费。
因此,在实际应用中,尽量应该让同一个消费者组内的实例订阅相同的主题,以充分发挥消费者组的优势,避免不必要的问题
2、队列
在创建主题时,可以指定该主题包含的队列数量。RocketMQ 会根据配置在相应的 Broker 上创建指定数量的消息队列。此外,在一些动态扩展的场景下,也可以根据实际需求动态地增加队列数量,以适应业务流量的变化。
通常情况下,1个消息只会放在1个消息队列中,而每个消息队列在同一时间只会被一个消费者实例消费,所以每条消息仅被一个实例处理。不过在一些特殊情况,比如广播模式,当消费者组以广播模式消费消息时,RocketMQ 会将每条消息发送到所有队列,这样每个队列都会有相同的消息。在这种模式下,不管消息在哪个队列中,每个消费者实例都会收到主题下的所有消息。
一个队列只能在同一时间只能分配给一个消费者进程,而一个消费者进程可以同时消费多条队列中的消息。