Вопрос или проблема
У меня есть 2 приложения SpringBoot, развернутых в AWS, APP1 управляет автомобилями, и для каждого нового добавленного автомобиля он создаст 2 темы kafka, которые будут использоваться только для этого автомобиля (тема A для событий APP1 -> APP2 и тема B для событий APP2 -> APP1).
После их создания APP1 отправит событие в APP2, чтобы начать обработку этого автомобиля (непрерывная асинхронная задача), и время от времени APP2 также будет отправлять некоторые события на тему автомобиля обратно в APP1, чтобы сигнализировать о некоторых событиях с этим автомобилем. Поскольку в какой-то момент у APP2 не будет достаточной мощности, у меня будет дополнительный экземпляр, но я не уверен, как лучше всего управлять коммуникацией APP1 -> APP2 с несколькими экземплярами APP2, которые имеют мощность (потому что в какой-то момент очень перегруженный экземпляр может стать менее перегруженным).
Проблема в том, что если у меня есть все экземпляры в одной группе потребителей, только один получит сообщение о начале обработки автомобиля, но если у него нет мощности, как я могу найти другой экземпляр для выполнения задачи?
Еще одна идея, о которой я думаю, заключается в том, чтобы, когда я отправляю событие из APP1, у меня были бы экземпляры APP2 в разных группах потребителей, чтобы каждый экземпляр получил событие о начале обработки автомобиля, но как убедиться, что только один из них обрабатывает его?
Ответ или решение
Вопрос о том, как эффективно управлять обработкой сообщений Kafka в среде с несколькими экземплярами приложения (в данном случае, экземплярами приложения APP2), является актуальной темой в архитектуре микросервисов. В данной ситуации необходимо учесть особенности работы с Kafka, а также решения, которые помогут обеспечить надежную обработку сообщений с учетом различной нагрузки на экземпляры APP2.
Анализ Ситуации
У вас есть два приложения, APP1 и APP2, которые взаимодействуют через Kafka. Каждое новое событие (например, добавление машины) инициирует создание двух тем: Тема A для передачи событий от APP1 к APP2 и Тема B для обратной связи от APP2 к APP1. Когда APP1 отправляет событие на обработку в APP2, важно, чтобы это событие обрабатывало только одно приложение, при этом необходимо учитывать возможные проблемы с нагрузкой.
Проблема с Обрабатывающими Экземплярами
Если все экземпляры APP2 находятся в одной группе потребителей, то сообщение будет обработано только одним из них, даже если у него недостаточно ресурсов. Это может привести к задержкам в обработке событий, особенно в пиковые моменты нагрузки.
Возможные Решения
-
Использование Несколько Групп Потребителей:
- Одна из стратегий заключается в том, чтобы организовать группы потребителей так, чтобы разные экземпляры APP2 находились в отдельных группах. Однако это приведет к тому, что все экземпляры получат данное сообщение, и вам необходимо будет реализовать логику для управления кросс-экземплярной блокировкой. Например, можно использовать вспомогательный механизм, такой как Redis или базу данных, для хранения статуса обработки сообщения, чтобы удостовериться, что только один из экземпляров продолжает обработку.
-
Использование Распределенной Блокировки:
- При отправке события от APP1 вы можете использовать механизмы распределенной блокировки. Перед тем, как начать обработку, каждый экземпляр APP2 должен будет попытаться захватить блокировку. Если экземпляр успешен, он выполняет обработку; если нет – получает сообщение, что обработка уже запущена. Это позволит избежать обработки одного и того же события одновременно несколькими экземплярами.
-
Динамическое Балансировка Нагрузки:
- Ваша архитектура может также включать API для проверки состояния нагрузки на APP2 экземпляры. Например, APP1 может сопоставлять текущую нагрузку каждого APP2 и направлять новое событие тому экземпляру, который менее загружен. Это решение потребует разработки механизма мониторинга состояния загрузки экземпляров.
-
Использование Топиков Разделённых По Задачам:
- Рассмотрите возможность использования отдельных тем для каждой задачи. Например, для разных типов обработок можно создать разные топики. Это поможет в более четком разделении задач и уменьшит вероятность заблокированных сообщений.
Заключение
Управление обменом сообщениями между многими экземплярами приложения с использованием Kafka требует продуманного подхода. Выбор между распределенной блокировкой, динамической балансировкой нагрузки или использованием разных групп потребителей зависит от специфики вашего приложения и архитектурных предпочтений. Каждое решение имеет свои плюсы и минусы, и важно выбрать наиболее подходящее для конкретной ситуации.
Основная цель – это обеспечить надежность и производительность обработки сообщений, что повысит общую эффективность системы.