首页 > 解决方案 > Spring Cloud Stream消费者负载均衡策略

问题描述

根据 Spring Cloud Stream 文档:

当有多个消费者实例绑定到相同的组名时,消息会在这些消费者实例之间进行负载平衡,以便生产者发送的每条消息仅由每个组中的单个消费者实例使用。

我想了解在这种情况下使用的负载平衡策略。此外,想了解使用以下属性如何影响消费者的负载平衡,

spring.cloud.stream.bindings.input.consumer.concurrency
spring.cloud.stream.<binder>.bindings.input.consumer.prefetch

在我们的例子中,binder 是 RabbitMQ。

我们的消费者应用程序只是一个传递,没有任何重要的逻辑。我们的有效载荷是大约 2 KB 大小的纯文本消息。产生给消费者进行处理的负载是 10K 消息。

当我们具有以下配置并运行多达 4 或 5 个消费者实例时,

spring.cloud.stream.bindings.input.consumer.concurrency=10
spring.cloud.stream.rabbit.bindings.input.consumer.prefetch=5

负载似乎是均匀分布的,但是当我们开始将实例增加到 5 个以上时,分布就不那么均匀了,即,其中一个实例开始接收更多负载,而其他实例处于空闲状态或只是不平均分担负载。

但是,如果我们开始减少并发和预取值,我们会开始看到实例之间的一些均匀分布,即,使用以下属性和最多 10 个实例,我们观察到均匀分布。

spring.cloud.stream.bindings.input.consumer.concurrency=2
spring.cloud.stream.rabbit.bindings.input.consumer.prefetch=1

拥有instanceCountandinstanceIndex属性,似乎不会产生预期的结果。

spring.cloud.stream.instanceCount
spring.cloud.stream.instanceIndex

不过,我们理解这些instanceCountinstanceIndex属性在分区环境中更有意义。由于 RabbitMQ 不是自然分区的,我们可能看不到差异。

看起来我们应该能够在我们的生产者中添加自定义分区策略,以使用 RabbitMQ 将负载分散到队列中。然而,我们将不得不改变我们的有效载荷结构来引入这样的策略。

但是,在此之前,我们想了解是否有一种有效的方法来通过使用消费者属性中的最佳值来进行负载平衡。

标签: javaspring-bootrabbitmqspring-cloud-stream

解决方案


推荐阅读