SmtpClient 非常慢 - 发送一封非常小的电子邮件大约需要 2 秒

发布于 2024-11-02 06:10:31 字数 663 浏览 5 评论 0原文

我正在使用 SmtpClient 发送简单的电子邮件。

该电子邮件由大约 25 个纯文本字符组成,因此很小。

然而,SmtpClient 需要大约 2000 毫秒才能发送其中一个。我不会为每个发送创建 SmtpClient - 这是在程序启动时创建的,所以唯一要做的就是:

DateTime start = DateTime.Now;

MailMessage oMsg = new MailMessage();
// TODO: Replace with sender e-mail address.
oMsg.From = new MailAddress(settings._Username);
oMsg.To.Add(new MailAddress(emailEvent._ContactItemToUse.Data));
oMsg.Subject = emo._Subject;
oMsg.BodyEncoding = Encoding.UTF8;
oMsg.IsBodyHtml = emo._IsHtmlText;
oMsg.Body = emo._Text;
client.Send(oMsg);
TimeSpan timeWasted = DateTime.Now.Subtract(start); // between 1000-2000 ms

这当然非常糟糕,我不明白为什么。我可以改进吗?

I'm using SmtpClient to send a simple email.

The email consists of about 25 plaintext characters so it's small.

It however takes the SmtpClient about 2000 milliseconds to send one of them. I do not create the SmtpClient for each send - that is created on program start so the only thing that is done is this:

DateTime start = DateTime.Now;

MailMessage oMsg = new MailMessage();
// TODO: Replace with sender e-mail address.
oMsg.From = new MailAddress(settings._Username);
oMsg.To.Add(new MailAddress(emailEvent._ContactItemToUse.Data));
oMsg.Subject = emo._Subject;
oMsg.BodyEncoding = Encoding.UTF8;
oMsg.IsBodyHtml = emo._IsHtmlText;
oMsg.Body = emo._Text;
client.Send(oMsg);
TimeSpan timeWasted = DateTime.Now.Subtract(start); // between 1000-2000 ms

This is of course very bad, and I can't figure out why. Can I improve it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

北陌 2024-11-09 06:10:31

我相信 SmtpClient 类不会为发送的每封邮件重用相同的连接(编辑:显然这在 .NET 4.0 中现在是可能的,请参阅文档中的差异 SmtpClient)。打开新连接的成本很高,而且可能需要时间。有些商业 SMTP 组件可以提供更高的性能。根据 SMTP 服务器和邮件大小,可以达到至少 50 封邮件/秒。

但是,如果您稍微更改架构,这对您来说可能不是问题。我在应用程序中所做的是,SmtpClient 通过使用 smtpClient.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory 并将 PickupDirectoryLocation 设置为所需目录,将邮件传送到文件夹。它的作用是,不是通过网络发送邮件消息,而是将它们作为标准 mime 消息(.eml 格式)写入指定的文件夹。

在这里,您可以使用 IIS SMTP 服务器,也可以简单地创建另一个后台线程/进程来使用创建的 .eml 文件并将它们传递给收件人或另一个 SMTP 服务器。

我认为这种方法要优越得多,因为:

  • 发送邮件的客户端代码永远不必等待实际的邮件发送,这可能需要相当长的时间,具体取决于连接速度、延迟等。
  • 如果邮件发送不成功,客户端代码不受影响。邮件可以在后台其他时间发送。
  • 邮件队列是持久性的,如果应用程序停止并再次启动,队列中的邮件不会丢失。
  • 更容易用于测试目的。

作为一种更简单的方法,您可以使用 SendAsync 而不是 Send,但它不会提供 PickupDirectory 方法将提供的所有直接方法。

The SmtpClient class I believe does not reuse the same connection for each mail sent (edit: apparently this is now possible in .NET 4.0, see the differences in documentation for SmtpClient). Opening a new connection is expensive, and that is probably what takes time. There are commercial SMTP components that do and offer much higher performance. Depending on SMTP server and mail size, it is possible to achieve something like at least 50mails/second.

However this might not be an issue for you if you change the architecture slightly. What I do in my application is that SmtpClient delivers mails to a folder, by using smtpClient.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory and setting the PickupDirectoryLocation to the wanted directory. What this does is, instead of sending the mail messages over the network, it will write them to the specified folder as standard mime messages (.eml format).

Here you can either use the IIS SMTP server or simply make another background thread/process to consume the .eml files created and deliver them to the recipients or to another SMTP server.

This approach I think is much superior, simply because:

  • The client code sending the mail never has to wait for the actual mail to be sent, which can take a fair while depending on connection speed, latency etc.
  • If the mail sent did not succeed, the client code is not affected. The mail can be sent some other time in the background.
  • The mail queue is persistent, if the application is stopped and started again, mails in the queue will not be lost.
  • Easier for testing purposes.

As a simpler approach, you can use SendAsync instead of Send, but it doesn't give all the immediate approaches the PickupDirectory approach will give.

等风来 2024-11-09 06:10:31

我想到了一些事情。

首先,一些网站会故意减慢连接速度,以降低垃圾邮件发送者向其系统发送邮件的利润。这称为柏油防水。

有趣的是,您的站点用于广播的邮件服务器甚至可能打开了此功能。 (http://winzenz.blogspot.com/2005/ 12/enabling-smtp-tarpitting-in-windows.html

其他可能导致问题的事情是,如果接收邮件服务器的 DNS 设置的 TTL 很短和/或您的 Web 服务器有一些问题(例如死机)或过载)其 IP 设置中的 DNS 服务器。

A few things come to mind.

First off, some sites will purposely slow down the connection in order to make it less profitable for spammers to send mail to their systems. This is called Tarpitting.

Interestingly, the mail server your site uses to broadcast out might even have this turned on. ( http://winzenz.blogspot.com/2005/12/enabling-smtp-tarpitting-in-windows.html )

Other things that might cause issues is if the receiving mail server has a short TTL for it's DNS settings and/or YOUR web server has some bad (e.g. dead or overloaded) DNS servers in it's IP setup.

童话里做英雄 2024-11-09 06:10:31

SmtpClient 类的速度主要取决于您要连接的 SMTP 服务器&您的互联网连接速度。使用 SmtpClient.SendAsync 优化直通输出并创建最多 10 个或更多到 smtp 服务器的简化连接的最佳方法。毕竟,这与所有现代网络浏览器为加快浏览速度而采取的策略相同。

Speed of SmtpClient class is mostly dependent on the SMTP server that you're connecting to & your internet connection speed. The best way to optimize your through-output using SmtpClient.SendAsync and creating up to 10 or more streamlined connections to the smtp server. After all, this is same strategy of all the modern web browsers do to speed up browsing.

同尘 2024-11-09 06:10:31

到 2021 年,当在 Powershell 核心内使用 net.mail.SmtpClient 时,我每分钟收到大约 580..620 封邮件。

如果我让脚本的 2 个实例在同一台服务器上运行(当然具有不同的电子邮件地址列表),第一个实例的速度约为 350..400 封邮件/分钟,第二个实例的速度约为 500..550 封邮件/分钟分钟。

就我而言,邮件是 HTML 格式的邮件,每封邮件中包含 4 个图像,并且每封邮件都必须单独生成。

因此 net.mail.SmtpClient 本身绝对慢。

当然,这在很大程度上取决于 SMTP 服务器的性能以及发送客户端和 SMTP 服务器之间的连接。

我们在生成电子邮件的服务器和我们的 SMTP 服务器之间拥有企业级 SMTP 解决方案和 GBit/s LAN。

这是使用 smtp.send(),而不是 smtp.sendAsync()。因此,每封邮件都会按顺序生成并等待 SMTP 服务器接受它。

在我看来,net.mail.SmtpClient确实可以用来群发邮件,而且非常好用。

根据艰苦经验得出的免费提示:只需绝对确保在发送每封邮件后处理 Net.Mail.MailMessage 对象 - 否则“收件人”邮件地址会累积起来,最终会发送一个多次向同一收件人发送邮件,并且收件人可以在“收件人”字段中看到对方。

in 2021, I get about 580..620 Mails / Minute through, when using the net.mail.SmtpClient from within Powershell core.

If I let 2 instances of the script run on the same server (with different e-mail address lists of course) I get on the 1st one about 350..400 mails / min and on the 2nd one about 500..550 mails / min.

In my case, the mails are HTML-formatted mails with each 4 images in them and each of the mails has to be generated individually.

So net.mail.SmtpClient by itself is definitely not slow.

Of course, it heavily depends on the performance of your SMTP server - and the connection between your sending client and the SMTP server.

We have an enterprise-grade SMTP solution and GBit/s LAN between the Server which is generating the e-Mails and our SMTP server.

This is using smtp.send(), not smtp.sendAsync(). So every mail is generated sequentially and waits until the SMTP server has accepted it.

In my opinion, net.mail.SmtpClient really can be used for mass mailing and it is very easy to use.

Free tip made out of hard experience: Just make absolutely sure that you dispose the Net.Mail.MailMessage object after sending each mail - otherwise the "to" mailadresses do cumulate up and you are ending up sending a mail to the same recipient multiple times and the recipients see each other in the "to" field.

感性不性感 2024-11-09 06:10:31

也许这不是你的问题。要发送,服务器必须接收。根据您的服务器,这可能需要一些时间。您也验证了该部分吗?

Maybe it is not your problem. To send, a server has to receive,. Depending on your server that can take some time. Have you validated that part, too?

淡淡離愁欲言轉身 2024-11-09 06:10:31

尝试远程登录并模拟相关 smtp 服务器的协议,看看哪个命令实际上延迟了您的通信。

我的猜测是 RCPT TO 命令进行某种需要一些时间的验证。

Try telnetting and emulate the protocol to the smtp-server in question and see which command that actually delays your communication.

My guess is that the RCPT TO command makes some sort of validation that takes some time.

月竹挽风 2024-11-09 06:10:31

有同样的问题。每封电子邮件约 2 秒。

对于我们来说,这修复了它:

c:\windows\system32\set-receiveconnector "External - TLS Exempt" -MaxAcknowledgeDelay 0

配置接收连接器属性< /a>

had the same exact issue. ~2 seconds per email.

for us this fixed it:

c:\windows\system32\set-receiveconnector "External - TLS Exempt" -MaxAcknowledgeDelay 0

Configure Receive Connector Properties

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文