Могу ли я иметь некоторый код, постоянно работающий внутри Django, как демон - PullRequest
15 голосов
/ 30 июня 2011

Я использую mod_wsgi для обслуживания сайта django через Apache. У меня также есть некоторый код Python, который запускается как фоновый процесс (dameon?). Он продолжает опрашивать сервер и вставляет данные в одну из моделей Django. Это прекрасно работает, но могу ли я иметь этот код, являющийся частью моего приложения Django, и при этом иметь возможность постоянно работать в фоновом режиме? Это не должен быть процесс сам по себе, а искусство сайта Django, которое постоянно активно. Если да, не могли бы вы указать мне пример или документацию, которая помогла бы мне в этом?

Спасибо.

Ответы [ 3 ]

14 голосов
/ 30 июня 2011

Вы можете либо создать задание cron, которое будет запускать определенную вами функцию, либо - более продвинутый и, вероятно, рекомендуемый метод, включить celery в ваш проект (что на самом деле довольно просто).

10 голосов
/ 30 июня 2011

Вы можете создать фоновый поток из сценария WSGI при его первом импорте.

import threading
import time

def do_stuff():
    time.sleep(60)
    ... do periodic job

_thread = threading.Thread(target=do_stuff)
_thread.setDaemon(True)
_thread.start()

Чтобы это работало, хотя вам бы пришлось использовать только один процесс-демон, иначе каждый процесс будет делать то же самое, чего вы, вероятно, не хотите.

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

Вы можете сделать это, набрав:

WSGIDaemonProcess django-jobs processes=1 threads=1
WSGIImportScript /usr/local/django/mysite/apache/django.wsgi \
    process-group=django-jobs application-group=%{GLOBAL}

Директива WSGIImportScript говорит, что нужно загрузить этот скрипт и запустить его при запуске в контексте группы процессов 'django-jobs'.

Чтобы сохранить наличие нескольких сценариев, я указал на то, каким будет исходный файл сценария WSGI, который вы использовали для WSGIScriptAlias. Мы не хотим, чтобы он запускался, когда он загружен этой директивой, поэтому мы делаем:

import mod_wsgi

if mod_wsgi.process_group == 'django-jobs':
    _thread = threading.Thread(target=do_stuff)
    _thread.setDaemon(True)
    _thread.start()

Здесь он смотрит на имя группы процессов демона и запускается только при запуске в специальной группе процессов демона, настроенной только для одного процесса.

В целом, вы просто используете Apache в качестве крупного прославленного менеджера процессов, хотя он уже известен как надежный. Это немного излишне, так как этот процесс потребляет дополнительную память в дополнение к тем, которые принимают и обрабатывают запросы, но в зависимости от сложности того, что вы делаете, он все еще может быть полезен.

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

WSGIDaemonProcess django-jobs processes=1 threads=1
WSGIImportScript /usr/local/django/mysite/apache/django.wsgi \
    process-group=django-jobs application-group=%{GLOBAL}

WSGIDaemonProcess django-site processes=4 threads=5
WSGIScriptAlias / /usr/local/django/mysite/apache/django.wsgi

WSGIProcessGroup django-site
WSGIApplicationGroup %{GLOBAL}

<Location /admin>
WSGIProcessGroup django-jobs
</Location>

Здесь все URL-адреса, кроме содержимого в / admin, запускаются в 'django-site', а / admin в 'django-jobs'.

В любом случае, это решает конкретный вопрос о том, как сделать это в процессе демона Apache mod_wsgi в соответствии с запросом.

Как указывалось, альтернативой является наличие сценария командной строки, который устанавливает и загружает Django, выполняет работу и выполняет ее из задания cron. Сценарий командной строки означает временное временное использование памяти, но стоимость запуска для работы выше, так как нужно каждый раз загружать все.

0 голосов
/ 05 июля 2011

Ранее я использовал работу cron, но говорю вам, что через некоторое время вы переключитесь на сельдерей.Кроме того, вы можете выполнять долгий асинхронный процесс, чтобы ускорить время запроса / ответа.

...