与ASP.NET的并发SMTP会话

时间:2014-05-02 03:13:45

标签: asp.net asp.net-mvc smtp

我正在使用ASP.NET MVC(旧版本是ColdFusion)构建的Windows 2008 VPS上启动新版本的调查系统。

系统操作的一个重要部分是每周向我们的订阅者发送一批10,000封电子邮件,然后完成一个简短的在线调查。

我使用VPS自己的SMTP服务器进行邮件发送,与旧版本相同,但发现批量邮件发送时间比以前长得多。

我的调查表明我的循环代码很有效,几乎所有的延迟都发生在实际的SMTP发送操作中。

研究进一步表明,在按顺序处理长邮件列表时会出现这种情况,并且电子邮件批次通常是通过提供与回调异步操作的多个并发SMTP会话的托管列表来完成的。据推测,这就是cfmail(我们之前使用过的)标签在幕后做的事情。

所以看起来我需要在ASP.NET中管理一系列System.Net.Mail.SmtpClent会话来复制这种行为,并使用SendAsync方法(它生成自己的线程来完成每个任务)。 / p>

我的问题是,在我们的服务器上,在启动邮件发送的HTTP请求中,是否有人可以看到这种方法同时运行多个线程以及最多10,20,50或100个SMTP会话的潜在问题?

1 个答案:

答案 0 :(得分:0)

这是一个很好的方法,但您不希望有太多的并发SMTP会话,原因如下:

  1. 如果通过SmtpClient.SendAsync()创建数十个或数百个线程,则会耗尽系统资源。 MSDN documentation for SendAsync没有明确说明每个调用创建一个线程,但它告诉您在前一个调用完成之前无法调用SendAsync。听起来这个类产生了自己的线程:

      

    "在调用SendAsync之后,您必须等待电子邮件传输完成后再尝试使用Send或SendAsync发送另一封电子邮件。"

  2.   
  3. 来自同一IP地址的多个同时连接是典型的垃圾邮件发送者行为。大多数邮件服务器限制来自同一IP地址的同时连接数,并最终可能将该地址列入黑名单。如果您可以控制目标SMTP服务器,则可以通过禁用IP地址限制来解决此问题。
  4.   
  5. 如果过快地发送过多邮件,并且目标邮件服务器未将您的IP地址列入白名单,则后者可能会放慢速度以减少其他SMTP客户端的资源。这种技术称为"tarpiting"。服务器通常限制每秒从给定IP接收的消息数。如果发生这种情况,增加线程数不会产生任何影响,您将不得不与邮件服务器管理员交谈,以便将您的IP地址列入白名单或增加限制。
  6.      所以,请使用您的解决方案,但将自己局限于少数SmtpClient实例(我将从4或5开始)。并使用共享线程安全的挂起MailMessage列表,每个SmtpClient将在调用其SendAsync()完成回调时选择要发送的下一条消息。