Храните состояние долгоживущих процессов в базе данных, а не в памяти
Долгоживущие процессы давно стали важной частью
Обычно нефункциональные требования в техническом задании не сформулированы, и о них никто кроме разработчика не думает. Чтобы сформулировать в явном виде нефункциональные требования, попробуйте ответить на следующие вопросы:
- Как понять, чем сейчас занимается долгоживущий процесс? Он работает или завис?
- Как понять, сколько задач он обработал за последние 10 минут? За полчаса? За сегодня?
- Что будет, если процесс упадет? (Да-да, ваш код, конечно, не падает, но обрыв соединения с базой данных и другими сервисами из-за проблем с сетью никто не отменял.) Зависнет ли обрабатываемая задача?
- Зависнет только одна задача? Или все N задач, попавшие в процесс?
- Продолжит ли выполняться задача после перезапуска процесса?
- Если продолжить выполнение задачи нельзя, вернется ли ответ в вызывающую систему об ошибочной ситуации?
- Позволяет ли ваша система потерять выполняемые задачи? Какие у вас требования к надежности? (На одной стороне шкалы надежности ежеминутное обновление какого-нибудь кеша, а на другой — обработка финансовых транзакций.)
Возможным решением проблем, на которые указывают эти вопросы, является хранение состояния долгоживущих процессов в базе данных, вместо хранения их в памяти приложения. Этот способ подойдет, если долгоживущие процессы выполняют задачи, связанные с обработкой некоторых сущностей, которые и так хранятся в базе данных. Тогда в эти сущности можно добавить поле со статусом обработки, или даже завести отдельную таблицу с задачами для долгоживущих процессов.
Какие преимущества получаем от хранения состояния долгоживущих процессов в базе данных?
Свобода в управлении процессами. Если процесс падает или его необходимо перезапустить, выполняемые задачи остаются в базе данных. При повторном запуске новый экземпляр проверяет и подхватывает незавершенные задачи. Это позволяет избежать потери данных или остановки процесса по выполняемым задачам.
Упрощение масштабирования. Если хранить данные в памяти процесса, легко попасть в ситуацию, когда разрабатывали в предположении одного запущенного процесса, и несколько процессов не смогут делить между собой задачи и выполнять их параллельно. Я сам такие процессы не писал, но часто слышу от коллег о подобных проблемах.
Простота мониторинга. В подготовленной системе мониторинга достаточно написать SQL-запрос, и новая метрика готова. Если же состояние хранится в памяти процессов, нужно дополнительно программировать отправку данных в систему мониторинга. Мониторинг дает представление о работе системы, выраженное в виде метрик (количество обработанных задач, время выполнения и другие показатели производительности). С помощью мониторинга заинтересованные лица оперативно и даже проактивно реагируют на проблемы.
Наблюдаемость состояния в админке. Когда состояние хранится в базе данных, его легко вывести в админке. Таким образом, вы сделаете работу приложения наблюдаемым. Иначе ваше рабочее время будет уходить на однотипные вопросы коллег, реагирующих на обращения пользователей: «что случилось с заявкой №782354, запрос ушел, но ответа не было?»
Когда не нужно хранить состояние долгоживущих процессов в базе данных? Когда вы сами понимаете, что в вашем случае написанное выше неприменимо. Если же противопоказаний нет, попробуйте обработку фоновых задач реализовать подобным образом.
Оставьте свой комментарий