От Hangfire к RabbitMQ: избавляемся от опроса базы данных
Hangfire отлично подходит для небольших команд. Вы просто добавляете NuGet-пакет и указываете на свою базу данных. В итоге вы бесплатно получаете планировщик задач и панель управления (dashboard). Для одного сервиса это решение трудно превзойти.
Я использовал Hangfire в проекте SavePosty для обработки электронных писем, вебхуков и получения контента. Каждая задача работала одинаково: они все опрашивали мою базу данных Postgres каждые несколько секунд, чтобы проверить наличие новой работы.
В итоге я перенес всё на RabbitMQ. Вот почему я это сделал и что при этом потерял.
Почему я перешел на RabbitMQ:
- Нагрузка от опроса (polling) растет со временем, а не с объемом работы. Каждая задача Hangfire обращается к вашей базе данных по таймеру. Даже если работы нет, база данных остается занятой. Эти затраты растут вместе с количеством задач и частотой опроса.
- Слишком много моделей. Одна часть моего приложения уже использовала RabbitMQ, а остальная — Hangfire. Это означало наличие двух разных способов управления фоновыми задачами. Переход на RabbitMQ позволил унифицировать процесс.
- Задержка (latency). Брокер передает задачу в тот же момент, когда она поступает. Hangfire же ждет следующего цикла опроса.
Компромиссы:
Hangfire легко настроить. Он использует ваши существующие SQL-таблицы и имеет отличную встроенную панель управления.
RabbitMQ требует управления брокером. Он использует оперативную память и сеть вместо ресурсов процессора базы данных. Вы получаете лучшее масштабирование, но увеличиваете операционные расходы.
Как я провел миграцию безопасно:
Я оставил бизнес-логику без изменений. Я создал «тонкие» потребители (consumers), которые работают как входная точка. Потребитель получает сообщение и передает его существующему классу задачи.
Я сосредоточился на двух вещах:
- Паритет повторных попыток (retry parity). Я настроил параметры повторных попыток в потребителе RabbitMQ так же, как в Hangfire, чтобы не терять сообщения.
- Безопасность схемы (schema safety). Я оставил старые колонки допускающими значение NULL, чтобы не нарушить работу базы данных во время развертывания.
Что я потерял:
Самый большой минус — это видимость. Hangfire позволяет кликнуть на упавшую задачу и увидеть, что именно произошло. RabbitMQ показывает, сколько сообщений находится в Dead Letter Queue, но не дает такого же удобного просмотра каждой отдельной задачи. Теперь я полагаюсь на структурированные логи вместо панели управления.
Мой совет:
Оставайтесь на Hangfire, если:
- У вас один сервис.
- У вас небольшая команда.
- Вам нужна простая панель управления для отладки.
Переходите на RabbitMQ, если:
- У вас несколько сервисов.
- Нагрузка на базу данных из-за опроса высока.
- Вы хотите использовать паттерны pub/sub.
Решение зависит от вашей системы, а не от одной конкретной задачи.
Source: https://dev.to/gabrielleroux/from-hangfire-to-rabbitmq-killing-database-polling-in-a-net-app-4og4
Optional learning community: https://t.me/GyaanSetuAi
