asp.net - Amazon SES 停止工作

标签 asp.net amazon-web-services smtp amazon-ses

我设置了 Amazon SES,它最初工作了几个小时,然后突然停止了。我发送的所有电子邮件以及我们的域都已经过验证。我们不会发送大量电子邮件——每天只有几百封。每当我对 web.config 进行更改时,它似乎可以让它再运行 2-3 个小时。例如,它停止工作,所以我将端口 587 切换到 25,它开始工作 2-3 小时,然后停止。然后我切换回587,同样的事情发生了。一旦它停止工作,它似乎永远不会自行重新开始。它运行在两个负载平衡服务器上,asp.net framework v2.0,IIS 7.5。这是我正在使用的代码:

网络配置:

<system.net>
  <mailSettings>
    <smtp deliveryMethod="Network" from="no-reply@ourdomain.com">
      <network defaultCredentials="false" host="email-smtp.us-east-1.amazonaws.com" userName="***" password="***" port="587" />
    </smtp>
  </mailSettings>
</system.net>

代码:
var smtpClient = new SmtpClient() { EnableSsl = true };

var mailMessage =
    new MailMessage(fromAddress, toAddress, subject, body)
    {
        IsBodyHtml = true
    };

smtpClient.Send(mailMessage);

这是我收到的两个错误:
The following exception was thrown by the web event provider '(null)' in the application '/' (in an application lifetime a maximum of one exception will be logged per provider instance):

System.Web.HttpException: Unable to send out an e-mail to the SMTP server. Please ensure that the server specified in the <smtpMail> section is valid. ---> System.Net.Mail.SmtpException: Failure sending mail. ---> System.IO.IOException: Received an unexpected EOF or 0 bytes from the transport stream.
   at System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count)
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
   at System.Threading.ExecutionContext.runTryCode(Object userData)
   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
   at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
   at System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32 size)
   at System.Net.Mail.SmtpConnection.Flush()
   at System.Net.Mail.ReadLinesCommand.Send(SmtpConnection conn)
   at System.Net.Mail.SmtpConnection.GetConnection(String host, Int32 port)
   at System.Net.Mail.SmtpClient.Send(MailMessage message)
   --- End of inner exception stack trace ---
   at System.Net.Mail.SmtpClient.Send(MailMessage message)
   at System.Web.Management.MailWebEventProvider.SendMail(MailMessage msg)
   --- End of inner exception stack trace ---
   at System.Web.Management.MailWebEventProvider.SendMail(MailMessage msg)
   at System.Web.Management.SimpleMailWebEventProvider.SendMessageInternal(WebBaseEventCollection events, Int32 notificationSequence, Int32 begin, DateTime lastFlush, Int32 discardedSinceLastFlush, Int32 eventsInBuffer, Int32 messageSequence, Int32 messagesInNotification, Int32 eventsInNotification, Int32 eventsLostDueToMessageLimit)
   at System.Web.Management.SimpleMailWebEventProvider.SendMessage(WebBaseEvent eventRaised)
   at *****.Global.SimpleMailWithSslWebEventProvider.ProcessEvent(WebBaseEvent raisedEvent)
   at System.Web.Management.WebBaseEvent.RaiseInternal(WebBaseEvent eventRaised, ArrayList firingRuleInfos, Int32 index0, Int32 index1)
The following exception was thrown by the web event provider '(null)' in the application '/' (in an application lifetime a maximum of one exception will be logged per provider instance):

System.Web.HttpException: Unable to send out an e-mail to the SMTP server. Please ensure that the server specified in the <smtpMail> section is valid. ---> System.Net.Mail.SmtpException: Service not available, closing transmission channel. The server response was: Timeout waiting for data from client.
   at System.Net.Mail.MailCommand.CheckResponse(SmtpStatusCode statusCode, String response)
   at System.Net.Mail.SmtpTransport.SendMail(MailAddress sender, MailAddressCollection recipients, String deliveryNotify, SmtpFailedRecipientException& exception)
   at System.Net.Mail.SmtpClient.Send(MailMessage message)
   at System.Web.Management.MailWebEventProvider.SendMail(MailMessage msg)
   --- End of inner exception stack trace ---
   at System.Web.Management.MailWebEventProvider.SendMail(MailMessage msg)
   at System.Web.Management.SimpleMailWebEventProvider.SendMessageInternal(WebBaseEventCollection events, Int32 notificationSequence, Int32 begin, DateTime lastFlush, Int32 discardedSinceLastFlush, Int32 eventsInBuffer, Int32 messageSequence, Int32 messagesInNotification, Int32 eventsInNotification, Int32 eventsLostDueToMessageLimit)
   at System.Web.Management.SimpleMailWebEventProvider.SendMessage(WebBaseEvent eventRaised)
   at *****.Global.SimpleMailWithSslWebEventProvider.ProcessEvent(WebBaseEvent raisedEvent)
   at System.Web.Management.WebBaseEvent.RaiseInternal(WebBaseEvent eventRaised, ArrayList firingRuleInfos, Int32 index0, Int32 index1)

我试图在亚马逊论坛上寻求帮助,但没有任何运气。似乎有什么东西干扰了连接,但我不知道是什么。有任何想法吗?谢谢。

最佳答案

这听起来确实是一个棘手的问题 - 我对此不是 100% 肯定,但您似乎错过了处理 SMTP 客户端,这在 Sending email is often very slow after changing to VPC instance 中提到。导致您看到的错误:

When I do not dispose of the SmtpClient, I get the error...

'Service not available, closing transmission channel. The server response was: Timeout waiting for data from client.'



这实际上是对间歇性问题的一个很好的解释,即根据执行的代码路径,此问题可能会触发 SMTP 连接到 Amazon SES挂起,这显然可以通过切换到另一个端口来补救,这意味着连接正在重置 - 这就是 SmtpClient.Dispose Method还确保:

Sends a QUIT message to the SMTP server, gracefully ends the TCP connection, and releases all resources used by the current instance of the SmtpClient class.



因此,合适的模式是促进 using Statement ,如 Getting Started with Amazon SES and .NET 中所示:
  String username = "SMTP-USERNAME";  // Replace with your SMTP username.
  String password = "SMTP-PASSWORD";  // Replace with your SMTP password.
  String host = "email-smtp.us-east-1.amazonaws.com";
  int port = 25;

  using (var client = new System.Net.Mail.SmtpClient(host, port))
  {
    client.Credentials = new System.Net.NetworkCredential(username, password);
    client.EnableSsl = true;

    client.Send
    (
              "FROM@EXAMPLE.COM",  // Replace with the sender address.
              "TO@EXAMPLE.COM",    // Replace with the recipient address.
              "Testing Amazon SES through SMTP",              
              "This email was delivered through Amazon SES via the SMTP end point."
    );
  }

请注意,示例使用的是端口 25,由于通常隐含的发送限制,我强烈建议避免使用该端口,有关相应 Amazon EC2 限制的详细信息,请参阅下面的附录。

祝你好运!

附录

端口 25 上的 Amazon EC2 节流

您可能已经意识到这一点(实际上我认为这不是问题),但是 Amazon EC2对通过端口 25 发送的电子邮件施加默认发送限制,如果您试图超过使用 Amazon SES 时仍然适用的那些限制,则限制出站连接。 ,见 Amazon SES SMTP Issues :

You are sending to Amazon SES from an Amazon EC2 instance via port 25 and you cannot reach your Amazon SES sending limits or you are receiving time outs — Amazon SES EC2 imposes default sending limits on email sent via port 25 and throttles outbound connections if you attempt to exceed those limits. To remove these limits, submit a Request to Remove Email Sending Limitations. You can also connect to Amazon SES via port 465 or port 587, neither of which is throttled.



因此,我会从您的测试/切换场景中删除端口 25 并仅使用端口 465/587 来代替,以避免错误的线索(正如所引述的,您也可以要求删除此限制,但这需要几个小时和端口 25 似乎最好首先避免) - 有点不幸的是,几个官方 Amazon SES 示例正在使用端口 25,甚至没有提到这个容易触发的问题。

关于asp.net - Amazon SES 停止工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14563200/

相关文章:

asp.net - 发出与 .NET 4.0 相同标记的 CSS 友好菜单适配器

json - 使用 aws cli 枚举 aws 标签

c# - 我正在构建一个 C# AWS Lambda 包。如何正确包含 System.Data.SqlClient.dll?

php - 通过运行 postfix 的单独电子邮件服务器从 php 应用程序发送电子邮件

c# - 页面加载后运行 Javascript

c# - 403 禁止 : Asp. 网络 MVC

c# - System.Web.httpApplicationFactory 类是什么?我在我的调用堆栈中看到它,但在框架中找不到它

java - 如何为 AWS Lambda 函数指定自定义配置?

服务器上的 PHPMailer smtp 连接失败

PHPMailer : MAIL not accepted from server: 530 5. 7.0 必须先发出 STARTTLS 命令