Согласно документации Spring Cloud Stream:
When there are multiple consumer instances bound with the same group name, then messages are load-balanced across those consumer instances so that each message sent by a producer is consumed by only a single consumer instance within each group.
Я хотел бы понять стратегию балансировки нагрузки, используемую в этом контексте. Кроме того, хотелось бы понять, как на балансировку нагрузки потребителей влияет использование следующих свойств:
spring.cloud.stream.bindings.input.consumer.concurrency
spring.cloud.stream.<binder>.bindings.input.consumer.prefetch
Связующим в нашем случае является RabbitMQ.
Наше потребительское приложение - это просто проход и не имеет какой-либо существенной логики. Наша полезная нагрузка - это текстовое сообщение размером ~ 2 КБ. Загрузка потребителя для обработки составляет 10К сообщений.
Когда у нас есть конфигурации, указанные ниже, и до 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
Наличие свойств instanceCount и instanceIndex, похоже, не дает желаемых результатов.
spring.cloud.stream.instanceCount
spring.cloud.stream.instanceIndex
Хотя мы понимаем, что эти свойства instanceCount и instanceIndex имеют больше смысла в многораздельной среде. Поскольку RabbitMQ не имеет естественного разделения, мы можем не заметить разницы.
Похоже, мы сможем добавить в наши производители собственную стратегию разделения, чтобы разделить нагрузку по очередям с RabbitMQ. Однако нам придется изменить нашу структуру полезной нагрузки, чтобы внедрить такую стратегию.
Но перед этим мы хотели бы понять, есть ли эффективный способ балансировки нагрузки, просто используя оптимальное значение в потребительских свойствах.
Спасибо!! Ваш комментарий заставил нас выявить первопричину. Мы не видели неподтвержденных сообщений в RabbitMQ. Но существует общая система кеширования, к которой экземпляры-потребители подключаются во время запуска и используют кеш во время обработки без какой-либо существенной бизнес-логики. Мы обнаружили здесь проблему с потоками, каждый поток создавал новые подключения к кешу вместо использования объединенного подключения. Из-за этого потоки блокировались, и это влияло на всю обработку. После того, как мы исправили это, мы видим равномерную балансировку нагрузки сообщений для всех экземпляров потребителей.




AMQP (и, следовательно, RabbitMQ) использует циклическую балансировку нагрузки между потребителями. Я немного не уверен, следил ли я за вашей настройкой, поэтому с точки зрения RabbitMQ было бы полезно увидеть, сколько неупакованных сообщений находится в системе, в то время как наблюдается неравномерная балансировка нагрузки.