Шаблон конкурирующих потребителей
(продолжение предыдущего поста)
Суть паттерна:
Шаблон конкурирующих потребителей (Competing Consumer Pattern) — это архитектурный шаблон, позволяющий нескольким потребителям (consumers) параллельно обрабатывать сообщения (задачи) из общей очереди. Цель — эффективно распределить нагрузку и повысить пропускную способность системы, обеспечив её отказоустойчивость
Компоненты на схеме:
1. Producers (производители) — генерируют задачи (сообщения), которые помещаются в очередь. На схеме это Admin API, отправляющие данные в хранилище (Storage) и очередь (Queue)
2. Queue (очередь) — централизованное хранилище сообщений, ожидающих обработки. Служит буфером между производителями и потребителями
3. File Processors Pool (пул процессоров файлов) — группа независимых потребителей (File processor), которые «соревнуются» за обработку сообщений из очереди. Каждый процессор обрабатывает только одно сообщение за раз
4. Consumers (потребители) — конечные сервисы, получающие результаты обработки (например, Products API на схеме)
5. Storage (хранилище) — место временного хранения данных (файлов), которые нужно обработать
Как работает паттерн (по схеме):
1. Producers отправляют задачи (например, файлы) в Storage и ставят сообщения о задачах в Queue.
2. File Processors Pool подписывается на очередь и «соревнуется» за сообщения: как только сообщение появляется в Queue, процессоры пытаются его «захватить».
3. Как только File processor получает сообщение, он:
- извлекает задачу (например, файл из Storage);
- обрабатывает её (например, преобразует или анализирует файл);
- отправляет результат в Consumers (Products API).
4. После успешной обработки процессор подтверждает получение сообщения — оно удаляется из очереди
5. Параллельная работа нескольких File processor обеспечивает увеличение пропускной способности (указано на схеме: «Parallel work to boost throughput»)
Ключевые особенности:
- Конкуренция: потребители «соревнуются» за сообщения — каждое сообщение обрабатывается только одним потребителем
- Параллелизм: несколько процессоров работают одновременно, что ускоряет обработку
- Отказоустойчивость: если один процессор выходит из строя, другие продолжают обработку
- Масштабируемость: можно добавлять процессоры для увеличения нагрузки
- Асинхронность: производители не ждут завершения обработки — задачи помещаются в очередь и обрабатываются позже
Пример из схемы:
- Admin API (производители) отправляют файлы в Storage и уведомляют Queue.
- File processor (из пула) забирает уведомление, читает файл из Storage, обрабатывает его и передаёт результат в Products API (потребители).
- Другие File processor параллельно обрабатывают другие файлы, конкурируя за сообщения в Queue.
Преимущества:
- оптимизация пропускной способности;
- балансировка нагрузки;
- устойчивость к сбоям отдельных потребителей;
- возможность горизонтального масштабирования (добавление процессоров)
Возможные проблемы:
- дублирование сообщений (требуется идемпотентная обработка);
- неравномерное распределение нагрузки;
- переполнение очереди при высокой нагрузке;
- «ядовитые сообщения» (poison messages), которые невозможно обработать
Шаблон конкурирующих потребителей идеально подходит для систем с переменной нагрузкой, где задачи независимы и могут выполняться параллельно — например, обработка изображений, отправка писем, анализ логов. Схема наглядно демонстрирует распределение ролей и взаимодействие компонентов в этом паттерне.
Post #3574
1.59K