Могу ли я иметь некоторый код, постоянно работающий внутри Django, как демон
Я использую mod_wsgi для обслуживания сайта django через Apache. У меня также есть некоторый код Python, который запускается как фоновый процесс (dameon?). Он продолжает опрашивать сервер и вставляет данные в одну из моделей Django. Это прекрасно работает, но могу ли я иметь этот код, являющийся частью моего приложения Django, и при этом иметь возможность постоянно работать в фоновом режиме? Это не должен быть процесс как таковой, но искусство сайта Django, которое постоянно активно. Если да, не могли бы вы указать мне пример или документацию, которая поможет мне в этом?
Благодарю.
3 ответа
Вы можете либо создать задание cron, которое будет запускать некоторую функцию, которую вы определили, либо - более продвинутый и, вероятно, рекомендуемый метод, включить сельдерей в ваш проект (что на самом деле довольно просто).
Вы можете создать фоновый поток из сценария 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. Сценарий командной строки означает случайное временное использование памяти, но стоимость запуска для работы выше, так как нужно каждый раз загружать все.
Раньше я использовал работу cron, но говорю вам, что через некоторое время вы переключитесь на сельдерей.
Сельдерей это путь. Кроме того, вы можете выполнять долгий асинхронный процесс, чтобы ускорить время запроса / ответа.