Советы по Python/Django и очередям сообщений
У меня есть приложение в Django, что нужно отправлять большое количество писем пользователям в различных случаях использования. Я не хочу обрабатывать это синхронно в приложении по очевидным причинам.
есть ли у кого-нибудь рекомендации для сервера очереди сообщений, который хорошо интегрируется с Python, или они использовались в проекте Django? Остальная часть моего стека-Apache, mod_python, MySQL.
10 ответов
до сих пор я не нашел "хорошего" решения для этого. У меня есть более строгие мягкие требования в реальном времени (фотографирование из картонной коробки с надписью), поэтому, вероятно, один из подходов достаточно быстр для вас. Полагаю, письма могут подождать несколько минут.
- "список задач" в базе данных, обработанной заданием cron.
- "список задач" в базе данных обрабатывается постоянно опрашиваемым демоном.
- использование пользовательского демона, который получает уведомление веб-сервером через пакет UDP (в производстве сегодня). В основном моя собственная система Queing со стеком IP для обработки очереди.
- использование ActiveMQ в качестве брокера сообщений - это не сработало из-за проблем со стабильностью. Также для меня Java-демоны обычно несколько пухлые
- использование триггеров обновления в CouchDB. Хорошие, но триггеры обновления не предназначены для тяжелой обработки изображений, поэтому не подходят для моей проблемы.
пока Я не пробовал RabbitMQ и XMPP/ejabebrd для обработки проблемы, но они находятся в моем списке следующих вещей, чтобы попробовать. RabbitMQ получил достойное подключение Python в 2008 году, и есть тонны библиотек XMPP.
но, возможно, все, что вам нужно, это правильно настроенный почтовый сервер на локальном компьютере. Это, вероятно, позволит вам сбрасывать почту синхронно в локальный почтовый сервер и, таким образом, сделать весь ваш стек программного обеспечения намного проще.
в вашем конкретном случае, когда это просто очередь электронной почты, я возьму простой выход и использую django-mailer. В качестве приятных побочных бонусов есть другие подключаемые проекты, которые достаточно умны, чтобы воспользоваться django-mailer, когда они видят его в стеке.
Что касается более общих решений очереди, я еще не смог попробовать ни одного из них, но вот список тех, которые выглядят более интересными я:
- pybeanstalk/beanstalkd
- интерфейс python для gearman (что, вероятно, намного интереснее сейчас с выпуском C версия gearman)
- memcacheQ
- топайте
- сельдерей
Stompserver-хороший вариант. Это легкий, простой в установке и простой в использовании от Django/python.
У нас есть система, использующая stompserver в производстве для отправки электронной почты и обработки других заданий асинхронно.
Django сохраняет электронные письма в базу данных, модель.обработчик post_save в Django отправляет событие в stompserver, а stompserver передает событие потребительскому процессу, который выполняет асинхронную задачу (отправляет электронное письмо).
Это весы довольно хорошо, потому что вы можете добавить потребительские процессы во время выполнения - два потребителя могут отправлять в два раза больше писем, и потребители могут быть на отдельных машинах. Одно небольшое осложнение заключается в том, что каждому потребителю нужна своя именованная очередь, поэтому Django должен знать, сколько потребителей доступно, и отправлять события в каждую очередь по кругу. (Два потребителя, слушающие в одной очереди, получат каждое сообщение = дублирование). Если вы хотите только один потребительский процесс, то это не вопрос.
ранее у нас были процессы, которые постоянно опрашивали базу данных для заданий, но обнаружили, что она добавляет много нагрузки в систему, даже когда ничего не нужно обрабатывать.
просто добавьте электронные письма в базу данных, а затем напишите другой скрипт, запущенный какой-то утилитой планировщика задач (cron приходит на ум), чтобы отправить электронные письма.
возможно, вы захотите взглянуть на pymq. Он написан на python, говорит HTTP с его клиентами и позволяет множество вариантов мониторинга и управления для очередей.
есть ли что-то неправильное в решении этого с помощью почтовой инфраструктуры? Например, каждый сервер приложений работает со своими почтовыми демонами, которые будут выстраивать в очередь любую локально отправленную почту, которая пересылается на централизованный почтовый сервер, который может выполнять тяжелую работу с почтой?
Если у вас уже установлен MySQL, вы можете создать таблицу для использования в качестве "списка задач".
потоки синхронно добавляют задания в таблицу, а пакетированная задача удаляет задания по мере их завершения.
таким образом, нет необходимости устанавливать и изучать больше программного обеспечения, и он должен работать нормально как постоянный магазин заданий, пока вы не отправляете много электронной почты (например, >10/сек).
вот ленивый, но правильное и адекватное решение. Используйте следующую таблицу в качестве очереди.
drop table if exists mailqueue;
create table mailqueue (
id bigint primary key,
subject text not null,
body mediumtext not null,
from varchar(255) not null,
to varchar(255) not null
);
отправители должны вставлять новые строки в конец этой таблицы.
настройка рабочих потоков для поп-почты по одному с другого конца (самый низкий идентификатор) и попытаться отправить их.
вы также можете использовать Twisted для этого. Но он не будет играть с Джанго во всех случаях, это очень зависит от сценариев развертывания. Самое главное, что каждый запрос должен обслуживаться одним процессом python, поэтому вам нужен Apache, скомпилированный в потоковом режиме.