Python / Django: отправка электронных писем в фоновом режиме

#python #django #django-email

#python #django #django-электронная почта

Вопрос:

Представьте ситуацию, в которой пользователь выполняет действие на веб-сайте, и администраторы уведомляются. Представьте, что нужно уведомить 20 администраторов. Используя обычные методы отправки электронных писем с помощью Django, пользователю придется подождать, пока все электронные письма не будут отправлены, прежде чем он сможет продолжить.

Как я могу отправить все электронные письма в отдельном процессе, чтобы пользователю не приходилось ждать? Возможно ли это?

Комментарии:

1. Альтернативным (простым) решением может быть отправка электронного письма на адрес Gmail (или другой), который затем будет использовать правило или что-то в этом роде и отправлять его всем администраторам

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

Ответ №1:

Используйте сельдерей в качестве очереди задач и django-celery-email, который представляет собой серверную часть электронной почты Django, которая отправляет отправку электронной почты в задачу сельдерея.

Комментарии:

1. могу я спросить одну вещь? Если я правильно понял, мне не нужно было бы изменять код моего приложения для реализации celery, за исключением моего settings.py . Правильно?

2. Пока вы используете django.core.mail API, вам не придется ничего менять в своем коде. Альтернативный сервер электронной почты заботится об интеграции сельдерея. Однако вы можете (легко) написать другие произвольные задачи сельдерея, которые будут выполняться в фоновом режиме, вне веб-процесса, что может быть очень удобно.

3. Я получил OperationalError: [Ошибка 111] Соединение отказано в комбу.

Ответ №2:

Другой вариант — django-mailer . Он ставит почту в очередь в таблице базы данных, а затем вы используете задание cron для их отправки.

https://github.com/pinax/django-mailer

Ответ №3:

Возможным решением может быть поток. Я интенсивно использую потоки в своем приложении для сложных задач.

 # This Python file uses the following encoding: utf-8

#threading
from threading import Thread

...

class afegeixThread(Thread):

    def __init__ (self,usuari, parameter=None):
        Thread.__init__(self)
        self.parameter = parameter
        ...

    def run(self):        
        errors = []
        try:
             if self.paramenter:
                   ....
        except Exception, e:                
             ...
...

n = afegeixThread( 'p1' )
n.start()
  

Комментарии:

1. Это возможно, но работа по-прежнему выполняется в процессе веб-сервера, что не идеально для фоновых задач. Если у вас есть возможность, вы должны настроить правильную очередь задач и максимально разгрузить веб-процессы.

2. Привет, Андреа, то, что ты говоришь, правда. На компьютере с 4 процессорами один из них работает на 100%, пока задачи не завершатся. На небольшом потоке сайта могут быть решения, но никогда на большом сайте. Но, как вы делаете, чтобы ставить в очередь интенсивные задачи django (в модели выполняется много операций)?

3. Я не совсем уверен, о чем вы спрашиваете, но celery создан для обработки асинхронных рабочих нагрузок за пределами веб-процессов, и это действительно легко и просто начать, см. Документы celery . Обычно хорошей практикой является разделение тяжелых заданий на более мелкие, если это возможно. Затем Celery можно запускать на нескольких компьютерах и выполнять задачи параллельно, что упрощает масштабирование и обработку тяжелых заданий! Это может, например, применяться для загрузки видео, изменения размера изображения, отправки электронных писем, создания PDF: файлов или других подобных тяжелых вещей!

4. Да, скорость, безусловно, самое элегантное решение. Но здесь мы говорим об отправке 20 электронных писем.