Стратегия балансировки нагрузки потребителей Spring Cloud Stream

Согласно документации 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. Однако нам придется изменить нашу структуру полезной нагрузки, чтобы внедрить такую ​​стратегию.

Но перед этим мы хотели бы понять, есть ли эффективный способ балансировки нагрузки, просто используя оптимальное значение в потребительских свойствах.

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

theMayer 27.09.2018 16:59

Спасибо!! Ваш комментарий заставил нас выявить первопричину. Мы не видели неподтвержденных сообщений в RabbitMQ. Но существует общая система кеширования, к которой экземпляры-потребители подключаются во время запуска и используют кеш во время обработки без какой-либо существенной бизнес-логики. Мы обнаружили здесь проблему с потоками, каждый поток создавал новые подключения к кешу вместо использования объединенного подключения. Из-за этого потоки блокировались, и это влияло на всю обработку. После того, как мы исправили это, мы видим равномерную балансировку нагрузки сообщений для всех экземпляров потребителей.

Sabari 29.09.2018 08:55
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
698
0

Другие вопросы по теме