在.NET中以高速率发送SMTP电子邮件

9
我有一个.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()的性能?我有哪些优化性能的选项?


这些邮件通常是相同的,只是发送给不同的收件人,还是电子邮件的内容不同? - Rob Levine
@Rob Levine:同一接收者,但是不同的内容。 - Martin Liversage
以每秒数百封的速度?谁想被埋在那么多的电子邮件下啊? - Ira Baxter
任何一个像样的SMTP服务器都会迅速将你的速度降至极低。 - Hans Passant
3个回答

8
SmtpClient类在后台缓存SMTP服务器连接。多次调用SmtpClient.Send()以将多个邮件提交到同一SMTP服务器,实际上会执行第二个示例中的伪代码。
改进性能的一种方法可能是在多个线程上运行多个SmtpClient实例。服务现在将具有许多并发连接而不是只有一个连接到SMTP服务器。传入的电子邮件消息从队列中取出并分派到调用SmtpClient.Send()将消息发送到SMTP服务器的工作线程池中。
我进行了一些初步测试,发现这可能会提高性能高达100%。但是,最佳并发连接数和实际性能改进可能非常依赖于SMTP服务器。扩展这个想法的一种方法是连接到多个SMTP服务器。

2
创建一个电子邮件服务器,使用线程池或其他方式异步发送电子邮件。这样,您就可以在服务器上“发射并忘记”电子邮件,并让它担心将它们全部发送出去。使用几个或更多线程进行设置,应该能够快速处理电子邮件。

这正是我们正在做的事情,只不过我们似乎遇到了一些性能问题。我的问题是关于从.NET服务中以最高效的方式"fire and forget"发送电子邮件的方法。 - Martin Liversage
什么性能问题?在我的实现中,我可以每分钟发送数千封电子邮件。它是否抛出异常?这在邮件中非常缓慢,因为您经常必须等待套接字超时。 - Chris
目前平均每秒发送20封电子邮件,但我们环境中有许多因素可能会影响这个数字。我正在调查是否可以改善邮件发送方面。 - Martin Liversage
如果我是你,我会设置一小段监控代码来检测发送速度较慢的电子邮件,并记录有关它们的信息。这样,您就可以快速找出是否有某些参数正在减慢它的速度。 - Chris

0

使用SMTP发送电子邮件的过程最初在RFC 821中指定。自那以后,已经进行了许多更新和添加,但基本协议仍然相同。您需要使用HELO命令开始每个事务,然后添加发件人信息、收件人等。如果您要将相同的消息发送给所有收件人,则可以在一条消息中添加多个收件人。但是,如果每个收件人的消息文本不同,我认为您需要向每个收件人发送单独的消息,这意味着每个消息都需要单独的事务。


1
我发现当重复调用SmtpClient.Send()时,它只会打开一次套接字,发出一个EHLO命令,然后在同一连接上提交多个MAIL FROM、RCPT TO和DATA命令。 - Martin Liversage

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接