gpt4 book ai didi

c# - 测试大量SMTP电子邮件发送代码的最佳方法?

转载 作者:太空狗 更新时间:2023-10-29 21:55:52 25 4
gpt4 key购买 nike

我已经在Windows服务(C#)中编写了一个组件,该组件负责发送有时大量的电子邮件。这些电子邮件将发送给许多域(实际上是任何域)上的收件人。 (是的,收件人想要电子邮件。否,我不是垃圾邮件。是的,我对CAN-SPAM投诉。是的,我知道sending email from code sucks。)许多电子邮件都是事务性的(响应用户而生成) Action );有些是批量的(基本上是邮件合并)。

我不想依赖外部SMTP服务器。 (除其他考虑外,不得不检查邮箱中的退回邮件并试图解析它们的想法给我带来了不好的感觉。)

我的设计很简单。事务消息和批量消息都将生成并插入到DB表中。该表包含电子邮件信封和内容,以及尝试次数和重试日期。

该服务运行一些工作线程,这些工作线程一次捕获20行,并遍历每个线程。使用Simple DNS Plus库,我获取收件人域的MX记录,然后使用System.Net.Mail.SmtpClient同步发送电子邮件。如果对Send()的调用成功,则可以使电子邮件出队。如果暂时失败,我可以增加尝试次数并设置适当的重试日期。如果它永久失败,我可以出队并处理失败。

显然,将数千封测试电子邮件发送到数百个不同的实际域是一个非常糟糕的主意。但是,我绝对需要对多线程发送代码进行压力测试。我也不太确定最好的方法是模拟SMTP的各种失败模式。另外,我想确保我摆脱了各种垃圾邮件控制方法(使用灰名单来命名与网络层最相关的东西)。

我最近发现我的ISP阻止了到除ISP的SMTP服务器之外的任何服务器上的端口25的连接,甚至使我的小规模测试困难也变得更加严重。 (在生产中,这东西当然会放在不阻塞端口25的适当服务器上。这无助于我在我的开发机上进行测试。)

因此,我最好奇的两件事是:

  • 我应该如何测试我的代码?
  • SmtpClient.Send()失败的各种方式是什么?列出了六个异常(exception)。 SmtpExceptionSmtpFailedRecipientsException似乎最相关。


  • 更新: Marc B's answer指出,我基本上是在创建自己的SMTP服务器。他提出了我正在重塑方向盘的正确观点,因此这是我不使用“实际的”(Postfix等)的理由:
  • 电子邮件具有不同的发送优先级(尽管这与信封的X-Priority无关)。批量电子邮件的优先级较低;交易性很高。 (并且任何电子邮件或一组电子邮件都可以进一步配置为具有任意优先级。)我需要能够暂停发送优先级较低的电子邮件,以便可以优先发送优先级较高的电子邮件。 (为此,工作线程每次获得另一个20时,便从队列中选择优先级最高的项。)

    如果我已经向外部SMTP服务器提交了数千个批量商品,那么当我希望提交的商品现在被发送时,我将无法保留这些商品。粗略的Google search显示Postfix并不真正支持优先级。 Sendmail优先处理信封中不符合我需要的信息。
  • 我需要能够向用户显示爆炸(群发电子邮件组)发送过程的进度。如果我只是将所有电子邮件都交给了外部服务器,那么我不知道实际交付的过程有多远。
  • 我很犹豫要解析退回邮件,因为每个MTA的退回邮件都是不同的。 Sendmail与Exchange的不同之处与[...]的不同之处。另外,我应该以什么频率检查我的退件箱?如果未发送退回邮件该怎么办?
  • 我不太担心爆炸中途失败。

    如果我们正在谈论灾难性故障(应用程序终止未处理的异常,电源故障等):由于工作线程在成功传递数据库后,会从数据库中将每封电子邮件从队列中拔出,所以我可以知道谁收到了爆炸,而谁没有收到爆炸。此外,当服务在失败后重置时,它只是从队列中停下来的地方接起。

    如果我们在谈论本地故障(一个SmtpException,DNS故障等):我只记录故障,增加电子邮件的尝试计数器,然后再试一次。 (基本上是SMTP规范所要求的。)经过n次尝试后,我可以使消息永久失败(将其出队),并记录失败以供以后检查。这样,即使我的代码不是100%完美,我也可以发现我的代码无法处理的怪异情况。 (说实话,事实并非如此。)
  • 我希望通过自行拥有的路由最终可以使我更快地发送电子邮件,而不必依赖于外部SMTP服务器。如果服务器不在我的控制之下,我将不得不担心速率限制。即使是这样,它仍然是一个瓶颈。我使用的多线程体系结构意味着我将并行连接到多个远程服务器,从而减少了传递n条消息所需的总时间。
  • 最佳答案

    假设您有两台服务器可用。一个将是发送者,一个将是接收者。您可以在带有大量伪造域名的两个域名上都设置DNS(甚至只是托管文件)。就这两个服务器而言,这些域是完全有效的,因为本地DNS服务器对其具有权威性,但对于其余的网络则完全无效。只要确保解析器在DNS之前检查主机文件即可。

    一旦完成,您就可以让发送服务器向接收服务器发送垃圾邮件,让接收服务器了解您的心脏内容,就像接收器执行各种操作来测试代码的 react 一样。灰名单,TCP延迟,硬跳,ICMP无法访问,ICMP跃点超过等。

    当然,由于必须测试所有这些条件,因此基本上是在创建自己的SMTP服务器,那么为什么不使用实际的SMTP服务器呢?我猜想对退回邮件进行一些基本解析所需的工作量将远远少于必须提供代码块来处理postfix/sendmail/exim/etc等所有失败模式的工作量……自己的。

    当您认为发送代码从一开始就必须是完美的时,尤其如此。如果电子邮件爆炸过程中途失败,并且只有一半的收件人列表接收到该邮件,则与数百或几千封邮件退回相比,您所处的困境要大得多。更糟糕的是,它以多种不同的方式失败(某些服务器无法访问,有些将您列入流量过大名单,等等。)。而在您手动处理退回邮件或修补退回邮件解析器以处理退回邮件之前,退回邮件将很高兴地坐在传入队列中。

    关于c# - 测试大量SMTP电子邮件发送代码的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3332574/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com