如何以python快速将邮件发送给成千上万的收件人,每个收件人在邮件标题中都显示为收件人? [英] How to send a mail to hundreds of thousands recipients in python fast which each of recipients is showed as receiver in mail header?

查看:245
本文介绍了如何以python快速将邮件发送给成千上万的收件人,每个收件人在邮件标题中都显示为收件人?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm looking of solutions to send huge number of mails (hundreds of thousands) in Python. I have a list of recipients (in a file), and I want to send a mail to all of them. I want each of recipients was show as receiver in mail header, not bcc or cc. Well, my solutions: send a separated mail to each of them not a mail to all list. I did some works below:(I used smtplib, threading):

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封邮件/秒)。因此,请帮助我加快速度。或建议我另一种解决方案来完成这项工作。

It work but very slow (about 6 mails/second). So please help me to make it faster. Or suggest me another solutions to do this job. Thank you very much!

推荐答案

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

Fastest would be to install a Mail Transfer Agent such as Postfix on your machine and hand all your emails to it for delivery using the /usr/sbin/sendmail mailing interface. Most reasonable mail servers can accept thousands of mail messages for delivery per second and may perform some SMTP pipelining to send a message to multiple recipients on a target domain in a single connection, drastically reducing traffic overhead and improving message throughput. (This wouldn't influence how your users see your emails.)

大多数邮件服务器还可以非常好地暂时关闭服务器,这非常重要,因为许多站点使用< a href = http://en.wikipedia.org/wiki/Graylisting rel = noreferrer>灰色列表以打击垃圾邮件。

Most mail servers can also handle temporarily down servers extraordinarily well, which is extremely important since many sites use greylisting to combat spam.

如果但是,您确实希望通过Python中的网络连接与SMTP服务器联系,使用线程池,它将使地址脱离队列,创建并发送电子邮件,然后返回队列以供其他地址使用。您当前的代码为每封邮件传递创建并销毁一个新线程。线程需要花费一些时间来创建和销毁它们,而所有开销都是本可以用于服务邮件的时间。

If, however, you really want to be contacting an SMTP server via a network connection in your Python, it would be a very good idea to use a thread pool of sending threads that will take addresses off a queue, create and send the email, and then return to the queue for another address to service. Your current code creates and destroys a new thread for every single mail delivery. Threads take time to create and take time to destroy, and all that overhead is time that could have been spent servicing your mails.

此外,线程池将限制总数活动连接数。建立与单个邮件服务器的1000个单独但同时的连接没有任何意义。设置每个会话的三向握手所花费的延迟是您的三倍服务器建立TCP会话之前,您可以发送任何SMTP通信。因此,创建具有十个连接的十个线程,然后将这些连接重用于发送电子邮件。 (即使是十个也算是过大了-两个或三个可能会更好。哎呀,一个线程可能是所有线程中最好的,尽管如果该连接断开(每个连接的邮件限制吗?),您在重新建立连接之前,将有一段时间通过有线方式发送什么。)

Furthermore, the thread pool would limit the total number of active connections. There's no point in creating 1000 separate but simultaneous connections to a single mail server. The three-way handshakes that set up each session take three times the latency to your server to establish the TCP session before you can send any SMTP traffic. So create ten threads with ten connections and reuse those connections for sending emails. (Even ten is probably overkill for this -- two or three would probably work better. Heck, one thread might be best of all, though if that connection goes down (per-connection mail limits?) you would have a period of sending nothing over the wire until that connection is re-established.)

您现在创建的内容非常相似打雷问题的问题–您启动了数百或数千个线程,但可能没有足够的内存来运行同时将它们全部保留在RAM中。您可能已经引入了足够的交换功能,从而大大降低了发送系统的性能,在该系统中,一个执行线程可能完全适合内存,并且运行时不会因交换而停顿。

What you've created now is very similar to the thundering herd problem -- you start hundreds or thousands of threads but might not have sufficient memory to keep them all in RAM simultaneously. You might have introduced enough swapping to drastically reduce the performance of your sending system, where a single thread of execution might fit entirely in memory and run without stalling for swapping.

这篇关于如何以python快速将邮件发送给成千上万的收件人,每个收件人在邮件标题中都显示为收件人?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆