Архитектура системы: простой подход к настройке фоновых задач за веб-приложением, будет ли он работать?

У меня есть веб-приложение Django, и у меня есть несколько задач, которые должны работать (или фактически запускаться) в фоновом режиме.

Приложение развертывается следующим образом:

  • apache2-mpm-рабочий;
  • mod_wsgi в режиме демона (1 процесс, 15 потоков).

Фоновые задачи имеют следующие характеристики:

  • они должны работать с регулярным интервалом (каждые 5 минут или около того);
  • им требуется контекст приложения (т. е. пакеты приложений должны быть доступны в памяти);
  • им не требуется никакого ввода, кроме доступа к базе данных, для выполнения некоторых не очень тяжелых задач, таких как отправка электронной почты и обновление состояния базы данных.

Теперь я подумал, что самый простой подход к этой проблеме будет заключаться в том, чтобы просто использовать существующий процесс приложения (порожденный mod_wsgi). Реализуя задачу как часть приложения и предоставляя для нее HTTP-интерфейс, я предотвратил бы накладные расходы другого процесса, который удерживает все приложение в памяти. Можно настроить простой cronjob, который отправляет запрос на этот HTTP-интерфейс каждые 5 минут, и на этом все. Поскольку процесс приложения обеспечивает 15 потоков, а задачи довольно легкие и выполняются только каждые 5 минут, я полагаю, что они не будут мешать производительности операций веб-приложения, обращенных к пользователю.

Тем не менее... Я провел некоторое онлайн-исследование и не видел, чтобы кто-то поддерживал этот подход. Во многих статьях предлагается значительно более сложный подход, основанный на полноценном компоненте обмена сообщениями (например, Celery, который использует RabbitMQ). Хотя это и сексуально, для меня это звучит как излишество. В некоторых статьях предлагается настроить cronjob, который запускает скрипт, выполняющий задачи. Но это тоже не кажется очень привлекательным, поскольку приводит к созданию нового процесса, который загружает все приложение в память, выполняет какую-то крошечную задачу и снова уничтожает процесс. И так повторяется каждые 5 минут. Не похоже на элегантное решение.

Итак, я ищу отзывы о предложенном мной подходе, описанном в абзаце перед предыдущим абзацем. Верны ли мои рассуждения? Не упускаю ли я из виду (потенциальные) проблемы? А как насчет моего предположения, что производительность приложения не пострадает?


person Tim Molendijk    schedule 21.04.2010    source источник


Ответы (2)


Все разумные подходы в зависимости от ваших конкретных требований.

Другой способ — запустить фоновый поток внутри процесса при загрузке сценария WSGI. Этот фоновый поток может просто засыпать и время от времени просыпаться для выполнения необходимой работы, а затем снова засыпать.

Однако этот метод требует, чтобы у вас был не более одного процесса Django, в котором работает фоновый поток, чтобы избежать выполнения одной и той же работы другой обработкой в ​​любой базе данных и т. д.

Использование режима демона с одним процессом удовлетворит этим критериям. Потенциально есть и другие способы добиться этого, даже в многопроцессорной конфигурации.

person Graham Dumpleton    schedule 21.04.2010
comment
Спасибо за предложение, Грэм. Помогает ли mod_wsgi настроить что-то подобное? Или мне придется построить его самостоятельно на Python? Я бы предпочел не выходить на минное поле, называемое многопоточным программированием, поскольку не уверен, что выберусь оттуда живым. - person Tim Molendijk; 21.04.2010
comment
Ваша конфигурация для режима демона уже многопоточная, поэтому вам все равно следует обратить на это внимание для вашего собственного кода вашего приложения Django. Что касается предоставления чего-то особенного, нет, вам просто нужно использовать модуль потоковой передачи для создания потока. - person Graham Dumpleton; 21.04.2010

Обратите внимание, что celery работает и без RabbitMQ. Он может использовать очередь гетто (SQLite, MySQL, Postgres и т. д., а также Redis, MongoDB), что полезно при тестировании или для простых настроек, где RabbitMQ кажется излишним.

См. http://ask.github.com/celery/tutorials/otherqueues.html (Использование Celery с Redis/базой данных в качестве очереди сообщений.)

person asksol    schedule 22.04.2010