2012-01-22 7 views
1

У меня есть приложение, которое отправляет клиентам более 1000 писем. Каждое электронное письмо настраивается для клиента. У меня есть приложение Django, использующее мою учетную запись Gmail Business (оплачивается для приложения Google) для отправки электронных писем.Django - отправка сообщений электронной почты - удаление SMTP-соединений

Проблема заключается в том, что после успешного отправления 80-100 писем соединение SMTP с Gmail падает. Я должен подождать около 10-15 минут, прежде чем я смогу снова начать отправку. Но, опять же после того, как около 70-100 сообщений электронной почты отправляются правильно, соединение будет удалено.

Я использую Django-Mailer-2 для отправки почты. Здесь ошибка, что мой Django приложение производит:

Traceback (most recent call last): 
    File "manage.py", line 11, in <module> 
    execute_manager(settings) 
    File "/usr/local/lib/python2.6/dist-packages/django/core/management/__init__.py", line 438, in execute_manager 
    utility.execute() 
    File "/usr/local/lib/python2.6/dist-packages/django/core/management/__init__.py", line 379, in execute 
    self.fetch_command(subcommand).run_from_argv(self.argv) 
    File "/usr/local/lib/python2.6/dist-packages/django/core/management/base.py", line 191, in run_from_argv 
    self.execute(*args, **options.__dict__) 
    File "/usr/local/lib/python2.6/dist-packages/django/core/management/base.py", line 220, in execute 
    output = self.handle(*args, **options) 
    File "/usr/local/lib/python2.6/dist-packages/django/core/management/base.py", line 351, in handle 
    return self.handle_noargs(**options) 
    File "/usr/local/lib/python2.6/dist-packages/django_mailer/management/commands/send_mail.py", line 47, in handle_noargs 
    send_all(block_size, backend=settings.USE_BACKEND) 
    File "/usr/local/lib/python2.6/dist-packages/django_mailer/engine.py", line 91, in send_all 
    blacklist=blacklist) 
    File "/usr/local/lib/python2.6/dist-packages/django_mailer/engine.py", line 179, in  send_queued_message 
    [message.to_address], smart_str(message.encoded_message)) 
    File "/usr/lib/python2.6/smtplib.py", line 697, in sendmail 
    self.rset() 
    File "/usr/lib/python2.6/smtplib.py", line 438, in rset 
    return self.docmd("rset") 
    File "/usr/lib/python2.6/smtplib.py", line 363, in docmd 
    return self.getreply() 
    File "/usr/lib/python2.6/smtplib.py", line 340, in getreply 
    raise SMTPServerDisconnected("Connection unexpectedly closed") 
smtplib.SMTPServerDisconnected: Connection unexpectedly closed 

Эти последние две строки заставляют меня думать, что Gmail закрывает соединение. Я столкнулся с Gmail, и они утверждают, что это мое программное обеспечение, которое вызывает проблему, а не их.

Как вы думаете?

+0

Вы пробовали сеанс telnet в Google MailService, когда ваше соединение падает? Просто проверить возможность подключения. – Jingo

ответ

2

OK - Я решил эту ситуацию. На самом деле, это больше работает. Я считаю, что Gmail останавливает мои письма, потому что они считают, что это спам. Отправка сотен электронных писем один за другим вызвала что-то на их конце и закрыла мое соединение. Это моя теория.

Моя работа добавляет строку кода в файл engine.py. После успешного отправления письма я добавил строку time.sleep(70). Это приводит к тому, что почтовая программа просто ждет 70 секунд, прежде чем продолжить. Я добавил этот код и попытался отправить все мои письма. Примерно через 7 часов было отправлено более 400 писем. Я бы сказал, что он работает. Он не должен быть быстрым, он просто должен работать. Мне было бы безразлично, если это займет несколько дней - до тех пор, пока они будут отправлены.

Спасибо за помощь.

0

В этом случае вы, скорее всего, может только сделать некоторые отладки: «/usr/lib/python2.6/smtplib.py», вокруг линии 697 выглядит следующим образом:

(code,resp) = self.mail(from_addr, esmtp_opts) 
    if code != 250: 
     self.rset() 
     raise SMTPSenderRefused(code, resp, from_addr) 

мне похоже, что сервер обрабатывает команду RSET, отменив соединение. Вы могли бы попробовать, если это так. Обрабатывая соединение вручную и выдавая команду rset().

Также этот код, как представляется, вызывается перед повышением исключения SMTPSenderRefused, поэтому это конкретное письмо не будет отправлено в любом случае.

Быстрое исправление может быть обезьяна патч, чтобы отключить команду RSET:

import smtplib 
smtplib.SMTP.rset = lambda self: 0 
+0

Это не очень хорошая идея, потому что соединение отказалось от сервера, и этот патч обезьяны не будет иметь никакого эффекта. –

+0

Ну, это, по крайней мере, даст соответствующую обратную связь о том, что вызвало сброс, в первую очередь, подняв соответствующее исключение. Более разумным патчем может быть «smtplib.SMTP.rset = smtplib.SMTP.close», чтобы закрыть сокет, который может позволить немедленное повторное подключение. – rumpel

+0

@rumpel: Я дам «smtplib.SMTP.close» попытку и отправлю отчет. Вы правы в отношении сообщений, которые даже не отправляются. В своем диалоге с поддержкой Gmail они продолжают запрашивать заголовки из затронутых писем, и я продолжаю говорить: «Письма не затрагиваются, это соединение». – Garfonzo

0

Очевидно, что существует некоторый предел скорости на стороне Google'd. Я нашел эту тему электронной почты, обсуждая проблему: http://blogoscoped.com/forum/112956.html

+0

Я знаю, что есть пределы. Для нашей платной услуги (Google Business Apps) предел составляет 2000 писем в сутки. Я не нахожу этого предела. Кроме того, каждое отправленное вами электронное письмо уникально - таким образом, «более 500 получателей» не применяются. – Garfonzo

3

Я столкнулся с тем же вопросом. Я принял ваше решение, но вместо того, чтобы спать после каждого письма, я отправляю 10 писем, а затем жду 70 секунд. Я смог успешно отправить более 200 писем таким образом. Когда я пытался спать каждые 50 писем, у меня все еще была проблема, и только 100 писем были отправлены до того, как соединение было отключено.

Смежные вопросы