【问题标题】:Django - sending lots of emails -- SMTP connection droppingDjango - 发送大量电子邮件 - SMTP 连接断开
【发布时间】:2012-02-16 09:04:53
【问题描述】:

我有一个应用程序可以向客户发送超过 1,000 封电子邮件。每封电子邮件都是为每个客户定制的。我有我的 Django 应用程序,使用我的 Gmail 业务帐户(为 Google 应用程序付费)发送电子邮件。

我遇到的问题是,在成功发送大约 80-100 封电子邮件后,与 Gmail 的 SMTP 连接断开。我必须等待大约 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,他们声称是我的软件导致了问题,而不是他们。

你怎么看?

【问题讨论】:

  • 当您的连接断开时,您是否尝试过在 google 邮件服务上进行 telnet 会话?只是为了验证连接的可能性。

标签: django gmail sendmail


【解决方案1】:

我遇到了同样的问题。我采用了您的解决方案,但不是在每封电子邮件后睡觉,而是发送 10 封电子邮件,然后等待 70 秒。通过这种方式,我能够成功发送 200 多封电子邮件。当我尝试每 50 封电子邮件休眠时,我仍然遇到问题,并且在断开连接之前仅发送了 100 封电子邮件。

【讨论】:

    【解决方案2】:

    好的——我解决了这个问题。真的,这更像是一种解决方法。我相信 Gmail 正在停止我的电子邮件,因为他们认为这是垃圾邮件。一个接一个地发送数百封电子邮件触发了他们的某些事情并关闭了我的连接。无论如何,这是我的理论。

    我的解决方法是在engine.py 文件中添加一行代码。邮件发送成功后,我添加了time.sleep(70)这一行。这会导致邮件程序在继续之前简单地等待 70 秒。我添加了此代码并尝试发送我所有的电子邮件。大约 7 小时后,成功发送了 400 多封电子邮件。我会说它有效。它不必很快,它只需要工作。我不在乎它是否需要几天——只要它们被发送。

    感谢您的帮助。

    【讨论】:

      【解决方案3】:

      在这种情况下,您很可能只能进行一些调试: “/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
      

      【讨论】:

      • 这不是一个好主意,因为连接被服务器拒绝,这个猴子补丁不会有任何效果。
      • 好吧,它至少会通过引发适当的异常,首先给出导致重置的原因的适当反馈。更智能的补丁可以是smtplib.SMTP.rset = smtplib.SMTP.close,也可以关闭套接字,这可能允许立即重新连接。
      • @rumpel:我会试试smtplib.SMTP.close 并报告。您甚至没有发送电子邮件是对的。在我与 Gmail 支持人员的对话中,他们不断询问受影响电子邮件的标头,我一直说:“电子邮件不受影响,连接受到影响。”
      • @rumpel:好吧,我添加了那条线并得到了相同的结果。不过,谢谢。
      【解决方案4】:

      显然,Google 方面存在一些速率限制。我找到了这个电子邮件线程,讨论了这个问题:http://blogoscoped.com/forum/112956.html

      【讨论】:

      • 我知道有限制。对于我们的付费服务 (Google Business Apps),限制为每 24 小时 2,000 封电子邮件。我根本没有达到这个极限。此外,我发送的每封电子邮件都是独一无二的——因此“超过 500 个收件人”不适用。
      猜你喜欢
      • 2012-06-23
      • 2021-02-07
      • 1970-01-01
      • 2014-08-31
      • 2011-07-30
      • 2015-11-24
      • 1970-01-01
      • 2010-11-15
      • 1970-01-01
      相关资源
      最近更新 更多