我有一个.NET服务,它处理后台线程上的队列,并从队列中的项目以非常高的速率发送大量的小电子邮件(如果是偶数,则说每秒100条消息)可能)。目前,我使用SmtpClient.Send()
,但我担心它可能会妨碍性能。
每次调用Send()
都会经历一个完整的循环,即打开套接字,执行SMTP会话(HELO,MAIL FROM,RCPT TO,DATA)并关闭套接字。在伪代码中:
for each message {
open socket
send HELO
send MAIL FROM
send RCPT TO
send DATA
send QUIT
close socket
}
(编辑:关于SmtpClient.Send()
的这句话实际上是假的,正如我在答案中解释的那样。)
我认为以下伪代码会更优化:
open socket
send HELO
for each message {
send MAIL FROM
send RCPT TO
send DATA
}
send QUIT
close socket
在以高费率发送电子邮件时,我是否应该关注SmtpClient.Send()
的效果?我有哪些优化性能的选择?
答案 0 :(得分:7)
SmtpClient
类正在后台缓存SMTP服务器连接。反复调用SmtpClient.Send()
以向同一SMTP服务器提交多条消息将有效地执行第二个示例中的伪代码。
提高性能的一种方法可能是使用在多个线程上运行的多个SmtpClient
实例。该服务现在具有许多并发连接,而不是仅与SMTP服务器建立一个连接。从队列中获取发送的电子邮件,并将其分派到调用SmtpClient.Send()
的工作线程池,以将邮件发送到SMTP服务器。
我做了一些基本测试,发现这可能会使性能提高100%。但是,最佳并发连接数和实际性能改进可能非常依赖于SMTP服务器。扩展此想法的一种方法是连接到多个SMTP服务器。
答案 1 :(得分:2)
创建一个电子邮件服务器,使用线程池或其他东西异步发送电子邮件。通过这种方式,您可以在服务器上“发送并忘记”您的电子邮件,并让它担心将它们全部发送出去。使用几个或更多线程进行设置,它应该能够快速地通过电子邮件发送。
答案 2 :(得分:0)
使用SMTP发送电子邮件的过程(最初)在RFC 821中指定。自那时以来已经有很多更新和补充,但基本协议仍然是相同的。您需要使用HELO命令启动每个事务,然后添加发件人信息,收件人等。如果要向所有收件人发送相同的邮件,则可以在一封邮件中添加多个收件人。但是,如果每个收件人的邮件文本不同,我认为您需要向每个收件人发送单独的邮件,这意味着每个邮件都有单独的交易。