Как реализовать приоритеты в микросервисе рассылки уведомлений
Что проверяют
Понимаете ли вы, что приоритет в очереди работает только при накопившемся хвосте и сам по себе не гарантирует, что срочное уйдёт быстро. Следом обычно спрашивают, как не уморить голодом низкий приоритет и что делать с лимитами внешних провайдеров.
Как отвечать
Начните с классов уведомлений: коды подтверждения и сброс пароля (секунды, иначе бесполезны), транзакционные (минуты), маркетинговые рассылки (часы, пачками). Дальше два рабочих подхода:
- отдельные очереди и отдельные воркеры:
notifications.high,.normal,.bulk, у каждой свой пул потребителей. Срочные получают зарезервированную мощность, и рассылка на миллион адресов их не задерживает. В Celery этоtask_routesи воркеры, запущенные с-Q; - приоритетная очередь RabbitMQ: классической очереди задаётся аргумент
x-max-priority, у сообщения выставляется свойствоpriority. Работает только при маломprefetch_count: если потребитель уже забрал сотню сообщений, новое срочное встанет за ними.
Kafka приоритетов внутри топика не знает вовсе, там заводят отдельные топики с отдельными группами потребителей.
Сильный ответ добавляет: TTL для кодов, чтобы протухший код не ушёл после затора; ключ идемпотентности, чтобы повтор не прислал два SMS; повторные попытки через отложенную очередь или DLX, а не в той же очереди; лимиты скорости по каналам (SMS, пуши через APNs и FCM, почта), потому что узкое место чаще у провайдера, чем у вас.
Где спотыкаются
Подписывают одного потребителя на три очереди через basic_consume в pika и считают это приоритетами. Брокер доставляет сообщения из всех трёх вперемешку, срочные ничем не выделены.
Ставят строгий приоритет без защиты низкого уровня. При постоянном потоке срочных сообщений рассылка не уходит никогда; нужна своя мощность или гарантированная доля для каждого уровня.
Утверждают, что Kafka поддерживает приоритетные очереди, или заводят сотни уровней через x-max-priority. Каждый уровень стоит брокеру памяти и процессора, документация RabbitMQ советует ограничиться несколькими, а практической пользы от большего числа нет.