傻瓜动态建站 工具,哪家公司建别墅好,商丘网站建设费用,做网站襄樊消费者从 Apache RocketMQ 获取消息消费时#xff0c;通过消费者负载均衡策略#xff0c;可将主题内的消息分配给指定消费者分组中的多个消费者共同分担#xff0c;提高消费并发能力和消费者的水平扩展能力。本文介绍 Apache RocketMQ 消费者的负载均衡策略。
背景信息
…消费者从 Apache RocketMQ 获取消息消费时通过消费者负载均衡策略可将主题内的消息分配给指定消费者分组中的多个消费者共同分担提高消费并发能力和消费者的水平扩展能力。本文介绍 Apache RocketMQ 消费者的负载均衡策略。
背景信息
了解消费者负载均衡策略可以帮助您解决以下问题 消息消费处理的容灾策略您可以根据消费者负载均衡策略明确当局部节点出现故障时消息如何进行消费重试和容灾切换。 消息消费的顺序性机制通过消费者负载均衡策略您可以进一步了解消息消费时如何保证同一消息组内消息的先后顺序。 消息分配的水平拆分策略了解消费者负载均衡策略您可以明确消息消费压力如何被分配到不同节点有针对性地进行流量迁移和水平扩缩容。
广播消费和共享消费
在 Apache RocketMQ 领域模型中同一条消息支持被多个消费者分组订阅同时对于每个消费者分组可以初始化多个消费者。您可以根据消费者分组和消费者的不同组合实现以下两种不同的消费效果 消费组间广播消费 如上图所示每个消费者分组只初始化唯一一个消费者每个消费者可消费到消费者分组内所有的消息各消费者分组都订阅相同的消息以此实现单客户端级别的广播一对多推送效果。 该方式一般可用于网关推送、配置推送等场景。 消费组内共享消费 如上图所示每个消费者分组下初始化了多个消费者这些消费者共同分担消费者分组内的所有消息实现消费者分组内流量的水平拆分和均衡负载。 该方式一般可用于微服务解耦场景。
什么是消费者负载均衡
如上文所述消费组间广播消费场景下每个消费者分组内只有一个消费者因此不涉及消费者的负载均衡。
消费组内共享消费场景下消费者分组内多个消费者共同分担消息消息按照哪种逻辑分配给哪个消费者就是由消费者负载均衡策略所决定的。
根据消费者类型的不同消费者负载均衡策略分为以下两种模式 消息粒度负载均衡PushConsumer和SimpleConsumer默认负载策略 队列粒度负载均衡PullConsumer默认负载策略
消息粒度负载均衡
使用范围
对于PushConsumer和SimpleConsumer类型的消费者默认且仅使用消息粒度负载均衡策略。
备注
上述说明是指5.0 SDK下PushConsumer默认使用消息粒度负载均衡对于3.x/4.x等Remoting协议SDK 仍然使用了队列粒度负载均衡。业务集成如无特殊需求建议使用新版本机制。
策略原理
消息粒度负载均衡策略中同一消费者分组内的多个消费者将按照消息粒度平均分摊主题中的所有消息即同一个队列中的消息可被平均分配给多个消费者共同消费。 如上图所示消费者分组Group A中有三个消费者A1、A2和A3这三个消费者将共同消费主题中同一队列Queue1中的多条消息。 注意 消息粒度负载均衡策略保证同一个队列的消息可以被多个消费者共同处理但是该策略使用的消息分配算法结果是随机的并不能指定消息被哪一个特定的消费者处理。
消息粒度的负载均衡机制是基于内部的单条消息确认语义实现的。消费者获取某条消息后服务端会将该消息加锁保证这条消息对其他消费者不可见直到该消息消费成功或消费超时。因此即使多个消费者同时消费同一队列的消息服务端也可保证消息不会被多个消费者重复消费。
顺序消息负载机制
在顺序消息中消息的顺序性指的是同一消息组内的多个消息之间的先后顺序。因此顺序消息场景下消息粒度负载均衡策略还需要保证同一消息组内的消息按照服务端存储的先后顺序进行消费。不同消费者处理同一个消息组内的消息时会严格按照先后顺序锁定消息状态确保同一消息组的消息串行消费。 如上图所述队列Queue1中有4条顺序消息这4条消息属于同一消息组G1存储顺序由M1到M4。在消费过程中前面的消息M1、M2被消费者Consumer A1处理时只要消费状态没有提交消费者A2是无法并行消费后续的M3、M4消息的必须等前面的消息提交消费状态后才能消费后面的消息。
策略特点
相对于队列粒度负载均衡策略消息粒度负载均衡策略有以下特点 消费分摊更均衡对于传统队列级的负载均衡策略如果队列数量和消费者数量不均衡则可能会出现部分消费者空闲或部分消费者处理过多消息的情况。消息粒度负载均衡策略无需关注消费者和队列的相对数量能够更均匀地分摊消息。 对非对等消费者更友好在线上生产环境中由于网络机房分区延迟、消费者物理资源规格不一致等原因消费者的处理能力可能会不一致如果按照队列分配消息则可能出现部分消费者消息堆积、部分消费者空闲的情况。消息粒度负载均衡策略按需分配消费者处理任务更均衡。 队列分配运维更方便传统基于绑定队列的负载均衡策略必须保证队列数量大于等于消费者数量以免产生部分消费者获取不到队列出现空转的情况而消息粒度负载均衡策略则无需关注队列数。
适用场景
消息粒度消费负载均衡策略下同一队列内的消息离散地分布于多个消费者适用于绝大多数在线事件处理的场景。只需要基本的消息处理能力对消息之间没有批量聚合的诉求。而对于流式处理、聚合计算场景需要明确地对消息进行聚合、批处理时更适合使用队列粒度的负载均衡策略。
使用示例
消息粒度负载均衡策略不需要额外设置对于PushConsumer和SimpleConsumer消费者类型默认启用。
SimpleConsumer simpleConsumer null;//消费示例一使用PushConsumer消费普通消息只需要在消费监听器处理即可无需关注消息负载均衡。MessageListener messageListener new MessageListener() {Overridepublic ConsumeResult consume(MessageView messageView) {System.out.println(messageView);//根据消费结果返回状态。return ConsumeResult.SUCCESS;}};//消费示例二使用SimpleConsumer消费普通消息主动获取消息处理并提交。会按照订阅的主题自动获取无需关注消息负载均衡。ListMessageView messageViewList null;try {messageViewList simpleConsumer.receive(10, Duration.ofSeconds(30));messageViewList.forEach(messageView - {System.out.println(messageView);//消费处理完成后需要主动调用ACK提交消费结果。try {simpleConsumer.ack(messageView);} catch (ClientException e) {e.printStackTrace();}});} catch (ClientException e) {//如果遇到系统流控等原因造成拉取失败需要重新发起获取消息请求。e.printStackTrace();} 队列粒度负载均衡
使用范围
对于历史版本服务端4.x/3.x版本的消费者包括PullConsumer、DefaultPushConsumer、DefaultPullConsumer、LitePullConsumer等默认且仅能使用队列粒度负载均衡策略。
策略原理
队列粒度负载均衡策略中同一消费者分组内的多个消费者将按照队列粒度消费消息即每个队列仅被一个消费者消费。 如上图所示主题中的三个队列Queue1、Queue2、Queue3被分配给消费者分组中的两个消费者每个队列只能分配给一个消费者消费该示例中由于队列数大于消费者数因此消费者A2被分配了两个队列。若队列数小于消费者数量可能会出现部分消费者无绑定队列的情况。
队列粒度的负载均衡基于队列数量、消费者数量等运行数据进行统一的算法分配将每个队列绑定到特定的消费者然后每个消费者按照取消息提交消费位点持久化消费位点的消费语义处理消息取消息过程不提交消费状态因此为了避免消息被多个消费者重复消费每个队列仅支持被一个消费者消费。
备注
队列粒度负载均衡策略保证同一个队列仅被一个消费者处理该策略的实现依赖消费者和服务端的信息协商机制Apache RocketMQ 并不能保证协商结果完全强一致。因此在消费者数量、队列数量发生变化时可能会出现短暂的队列分配结果不一致从而导致少量消息被重复处理。
策略特点
相对于消息粒度负载均衡策略队列粒度负载均衡策略分配粒度较大不够灵活。但该策略在流式处理场景下有天然优势能够保证同一队列的消息被相同的消费者处理对于批量处理、聚合处理更友好。
适用场景
队列粒度负载均衡策略适用于流式计算、数据聚合等需要明确对消息进行聚合、批处理的场景。
使用示例
队列粒度负载均衡策略不需要额外设置对于历史版本服务端4.x/3.x版本的消费者类型PullConsumer默认启用。
具体示例代码请访问RocketMQ代码库获取。
版本兼容性
消息粒度的负载均衡策略从 Apache RocketMQ 服务端5.0版本开始支持历史版本4.x/3.x版本仅支持队列粒度的负载均衡策略。
当您使用的 Apache RocketMQ 服务端版本为5.x版本时两种消费者负载均衡策略均支持具体生效的负载均衡策略依客户端版本和消费者类型而定。
使用建议
针对消费逻辑做消息幂等
无论是消息粒度负载均衡策略还是队列粒度负载均衡策略在消费者上线或下线、服务端扩缩容等场景下都会触发短暂的重新负载均衡动作。此时可能会存在短暂的负载不一致情况出现少量消息重复的现象。因此需要在下游消费逻辑中做好消息幂等去重处理。