Советы по 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, когда они видят его в стеке.

Что касается более общих решений очереди, я еще не смог попробовать ни одного из них, но вот список тех, которые выглядят более интересными я:

  1. pybeanstalk/beanstalkd
  2. интерфейс python для gearman (что, вероятно, намного интереснее сейчас с выпуском C версия gearman)
  3. memcacheQ
  4. топайте
  5. сельдерей

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, скомпилированный в потоковом режиме.