使用 asp.net 发送 20,000 多封电子邮件
Posted
技术标签:
【中文标题】使用 asp.net 发送 20,000 多封电子邮件【英文标题】:Sending out 20,000+ emails with asp.net 【发布时间】:2011-02-07 02:35:55 【问题描述】:我正在编写一个应用程序,该应用程序需要向我们的学生发送大量电子邮件,这些学生将从我们的数据库中选出(每封电子邮件都会个性化,包括他们的姓名、学习课程等...所以需要一次发送一个)。
我可以在 SmtpClient 上循环执行此操作,但我担心我尝试发送的数字最终会遇到超时问题,或者我的线程会因为缺乏机器资源而被杀死。
此时我只是在寻找更好的处理方法的建议,或者如果循环 SmtpClient 是一个好的解决方案,我应该如何处理它以防止我在上面发布的内容。
网络服务会是更好的选择吗?
请指教, TIA
【问题讨论】:
你需要使用一些第三方工具 你不需要使用一些第三方工具 【参考方案1】:我的建议是批量处理。不要尝试运行 ASP.NET 代码来创建 20K 电子邮件并将它们发送出去,因为您一定会遇到超时和性能问题。而是使用收件人、主题、正文填充表格并从 Windows 服务开始批处理。通过这种方式,您的代码以可以管理延迟的方式执行,而不是让网页等待请求返回。
【讨论】:
这种方法听起来很有希望。我已经将电子邮件保存在表格中。很抱歉提出一个愚蠢的问题,但是我将如何调用此 Windows 服务以使其启动电子邮件的发送,同样,我将如何向客户端报告哪些邮件已成功发送,哪些邮件从 Windows 服务发送失败? 您不必调用 Windows 服务。让它运行。该服务可以设计为检查您的餐桌,看看是否有任何工作要做。如果有电子邮件尚未发送,则将它们批量发送。基本上,该服务应该设计为每 5 分钟左右查询一次该表。 (请注意,您应该在该表上放置一个 bool 标志,说明它是否已发送,并且出于性能目的在 bool 标志上放置一个索引。)现在,当您查询表以查找所有未发送的项目时,如果计数大于 1,则服务开始发送电子邮件。至于向客户汇报 我的最后一条评论被截断了。至于向客户报告,您可以在网页上显示您的日志,说明天气或未发送电子邮件。此显示应分为两个视图。发送和未发送。 (小心这个,因为它可能是 20K 记录的长时间负载)。 关于 Windows 服务的另一个快速问题。我怎样才能将其分解,以免它一次尝试发送所有 20k 多封电子邮件?我认为我最终可能会遇到相同或类似的问题,除非我按照其他人在此处建议的“块”中进行处理.... 您的问题很快就被这种设计的美感所吸引。因为您只是在排队接收电子邮件。您可以将服务每 5 分钟运行一次的查询调整为 SELECT Top 100 * FROM MyMailTable where notsent = true。这样,每 5 分钟或您创建服务的任何时间间隔都会发送 100 封电子邮件。【参考方案2】:好的,首先 - 这并不大,我已经处理了 50.000 封电子邮件+
让电子邮件写入文件夹 - 目录。然后使用您可以安装的本地 SMTP 服务,将其指向作为拾取目录的文件夹。这至少可以确保您在两者之间有一个不错的缓冲区(即您可以完成 asp.net 端,而此时不发送电子邮件)。
【讨论】:
首先想到的问题是我们所有的学生都使用“第三方”作为他们的电子邮件(都使用相同的),我们的交换服务器被列入白名单为“正常”发件人”。不幸的是,我无法访问交换服务器来告诉它从这个“文件夹”中获取电子邮件......这一切都在我们的基础设施的肩上。我也无权在我们的第 3 方(所有电子邮件地址都在其中)上将 Web 服务器添加为“正常发件人”......所以不能在那里将其用作 smtp 服务器。如果我创建了一个网络服务来处理通过我们的交换发送电子邮件......那会飞吗 其实问题出在哪里?说真的...... LOCAL SMTP 服务可以配置为 (a) 使用交换服务器作为中继和 (b) 使用用户名和密码进行身份验证,就像使用普通 smtp 服务一样。 您的回答并没有提供任何解决方案,相反,您只是在问更多问题。您是否期望 20,000 名用户都使用同一个电子邮件提供商?您的回答表明您没有发送此类电子邮件的经验。 @Helen - 这是迟钝的。对不起。使用中继的电子邮件服务器将通过一个服务器发送所有电子邮件,就像任何其他服务器一样。这就是它的工作原理。他为所有 20.000 封电子邮件设置了相同的发件人,电子邮件服务器将找出发送邮件的位置。如果你不知道电子邮件是如何工作的,海伦,我建议你先起床阅读基础知识,而不是发表愚蠢的评论。任何电子邮件服务器(在这种情况下为交换服务器)都能够找到发送电子邮件的位置。 是的,我们就是这样做的,使用 SmtpClient 的 PickupDirectory 功能。目录中充满了由 GUID 命名的电子邮件。然后将它们复制到Exchange正在使用的“真实”拾取目录(我们使用临时目录,以防生成过程中途发生炸弹,我们没有错误发送一些电子邮件,可以删除并重新启动),然后 Exchange 吸收它们——不用担心过载,Exchange 足够聪明,一次只能吸收几个(尽管这是可配置的)。【参考方案3】:使用SQL Server本身提供的数据库邮件工具怎么样。您仍然可以使用 asp.net,但电子邮件将由 SQL Server 发送,您只需调用存储过程并将事情交给 SQL Server。
我不推荐批处理选项,因为除非您必须付出很多努力,否则不会有任何优化或排队的事情。
数据库邮件工具也提供队列和优先级选项。如果出现问题,电子邮件将再次排队并稍后发送,但其他邮件仍将发送。
在 SQL Server 2008 中称为 Database Mail,在以前的版本中称为 SQL Mail。
欲了解更多信息,请查看以下链接:
http://blog.sqlauthority.com/2008/08/23/sql-server-2008-configure-database-mail-send-email-from-sql-database/ http://msdn.microsoft.com/en-us/library/ms175887.aspx【讨论】:
那东西简直糟透了,从一开始就不应该在 SQL Server 中使用。 请忽略 TomTom - 他生来就喝醉了!你见过他的其他一些cmets吗? 我同意邮件发送程序可能不应该是数据库服务器的一部分,但事实仍然如此。这对于 OP 来说可能是一个很好的解决方案。【参考方案4】:您可以在计时器上使用 javascript 来请求以不会超时的小块发送邮件的脚本。然后你会从浏览器调用脚本。添加进度条、身份验证等。
【讨论】:
【参考方案5】:您不需要网络服务,而是一种将电子邮件批量放入队列的方法(可能是数据库中的“Email_Queue”表)。然后,在服务器上运行的 Windows 服务可以在发送到 SMTPClient 时以合理的块以先进先出的方式读取队列,在处理项目时从队列中删除它们。您可能需要运行一些测量来确定您的邮件服务器的块大小和延迟。
【讨论】:
以上是关于使用 asp.net 发送 20,000 多封电子邮件的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Codeigniter 通过 cc 发送多封电子邮件?