4

我正在寻找用 Python 发送大量邮件(数十万封邮件)的解决方案。我有一个收件人列表(在一个文件中),我想向所有收件人发送邮件。我希望每个收件人都显示为邮件标题中的收件人,而不是密件抄送或抄送。好吧,我的解决方案:向他们每个人发送单独的邮件,而不是向所有列表发送邮件。我在下面做了一些工作:(我使用了smtplib线程):

class SendMail(threading.Thread):
  def __init__(self, from, to, subject, message):
     self.from = from
     self.to = to
     self.subject = subject
     self.message = message 
  def run(self):
    try:
                msg = MIMEMultipart('alternative')
                msg['Subject'] = self.subject
                msg['From'] = self.from
                msg['To'] = self.to
                msg.attach(MIMEText(self.message , 'html'))
                server = smtplib.SMTP()              
                server.connect('xxxxx', 25)
                server.login('cxxxxx', 'yyyyyy')                
                server.sendmail(self.from, self.to, msg.as_string())
    except:
          pass

def sendmail():
   f = open('recipients','w')
   from = "me@mail.test"
   subject = "hello"
   message = "Hello Hello"
   for line in f.readlines():
      t = SendMail(from, line, subject, message)
      t.run()
   f.close()

它工作但很慢(大约 6 封邮件/秒)。所以请帮助我让它更快。或者建议我另一种解决方案来完成这项工作。非常感谢你!

4

2 回答 2

6

最快的方法是在您的计算机上安装邮件传输代理(例如Postfix),然后将所有电子邮件交给它,以便使用/usr/sbin/sendmail邮件界面进行传递。大多数合理的邮件服务器每秒可以接受数千封邮件消息进行传递,并且可以执行一些 SMTP 管道以在单个连接中将消息发送给目标域上的多个收件人,从而大大减少流量开销并提高消息吞吐量。(这不会影响您的用户如何查看您的电子邮件。)

大多数邮件服务器还可以非常好地处理暂时停机的服务器,这非常重要,因为许多站点使用灰名单来对抗垃圾邮件。

但是,如果您真的想通过 Python 中的网络连接联系 SMTP 服务器,那么使用发送线程的线程池将是一个非常好的主意,该线程池将从队列中取出地址,创建并发送电子邮件,然后返回队列等待另一个地址进行服务。您当前的代码为每个邮件传递创建和销毁一个新线程。线程需要时间来创建和销毁,所有这些开销都是本可以花费在服务邮件上的时间。

此外,线程池会限制活动连接的总数。为单个邮件服务器创建 1000 个独立但同时的连接是没有意义的。设置每个会话的三次握手需要三倍的延迟到您的服务器来建立 TCP 会话,然后您才能发送任何 SMTP 流量。因此,创建具有 10 个连接的 10 个线程,并重用这些连接来发送电子邮件。(即使是十个也可能是多余的 - 两个或三个可能会更好。哎呀,一个线程可能是最好的,但如果该连接断开(每个连接的邮件限制?)您将有一段时间什么都不发送直到重新建立连接。)

您现在创建的内容与雷鸣般的羊群问题非常相似——您启动了数百或数千个线程,但可能没有足够的内存将它们同时保存在 RAM 中。您可能已经引入了足够多的交换来显着降低发送系统的性能,其中单个执行线程可能完全适合内存并运行而不会因交换而停止。

于 2011-12-05T05:18:22.997 回答
1

我的建议(也是迄今为止最简单的)是将这项工作交给第三方,并在您的代码中调用他们的库。

MailChimp似乎很受欢迎(这是他们的api)。他们还提供慷慨的免费计划。

SocketLabs是另一种选择(这里是他们的api)。谷歌应该为您提供大量其他服务。

于 2011-12-05T06:12:03.907 回答