我正在寻找用Python发送大量邮件(数十万)的解决方案.我有一个收件人列表(在一个文件中),我想发送邮件给所有人.我希望每个收件人都显示为邮件标题中的接收者,而不是密件抄送或cc.好吧,我的解决方案:向每个邮件发送一个单独的邮件,而不是邮件发送到所有列表.我在下面做了一些工作:(我使用了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邮件/秒).所以请帮助我加快速度.或者建议我做另外一个解决方案.非常感谢你!
解决方法:
最快的方法是在您的计算机上安装Postfix等邮件传输代理,并使用/usr/sbin / sendmail邮件界面将所有电子邮件发送给它.大多数合理的邮件服务器每秒可以接受数千封邮件进行传递,并且可以执行一些SMTP流水线操作,以便在单个连接中向目标域上的多个收件人发送邮件,从而大大减少流量开销并提高邮件吞吐量. (这不会影响用户查看电子邮件的方式.)
大多数邮件服务器也可以非常好地暂时处理服务器,这非常重要,因为许多站点使用greylisting来打击垃圾邮件.
但是,如果您真的希望通过Python中的网络连接联系SMTP服务器,那么使用thread pool发送线程来获取队列中的地址,创建和发送电子邮件,以及然后返回队列以获取另一个服务地址.您当前的代码为每个邮件传递创建并销毁新线程.线程需要时间来创建并花费时间来销毁,所有这些开销都是花费在维护邮件上的时间.
此外,线程池将限制活动连接的总数.创建1000个单独但同时连接到单个邮件服务器是没有意义的.设置每个会话的three-way handshakes占用服务器的延迟时间的三倍,以便在您发送任何SMTP流量之前建立TCP会话.因此,创建具有十个连接的十个线程,并重用这些连接来发送电子邮件. (即使十个可能是矫枉过正 – 两个或三个可能会更好.哎呀,一个线程可能是最好的,但如果连接断开(每个连接邮件限制?)你会有一段时间没有发送通过电线直到重新建立连接.)
您现在创建的内容与thundering herd problem非常相似 – 您启动了数百或数千个线程,但可能没有足够的内存来将它们全部保存在RAM中.您可能已经引入了足够的交换来大幅降低发送系统的性能,其中单个执行线程可能完全适合内存并且在不停止交换的情况下运行.