亚马逊SES停止工作

Str*_*ped 15 asp.net smtp amazon-web-services amazon-ses

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

web.config中:

<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>
Run Code Online (Sandbox Code Playgroud)

c#代码:

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

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

smtpClient.Send(mailMessage);
Run Code Online (Sandbox Code Playgroud)

以下是我收到的两个错误:

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)
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)

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

Ste*_*pel 23

这听起来确实是一个棘手的问题 - 我不是100%肯定这一点,但你似乎错过了处理SMTP客户端,这在发送电子邮件中提到,在更改为VPC实例后通常非常慢,导致你的错误看到:

当我不处理SmtpClient时,我收到错误...

'服务不可用,关闭传输通道.服务器响应是:超时等待来自客户端的数据.

这对于间歇性问题实际上是一个很好的解释,即取决于执行的代码路径,这个问题可能会触发与Amazon SES的SMTP连接挂起,这显然可以通过切换到另一个端口来解决,这意味着连接被重置 - 这就是SmtpClient.Dispose方法也可以确保:

向SMTP服务器发送QUIT消息,正常结束TCP连接,并释放当前SmtpClient类实例使用的所有资源.

因此,适当的模式将是促进使用Statement,如Amazon SES和.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."
    );
  }
Run Code Online (Sandbox Code Playgroud)

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

祝好运!


附录

Amazon EC2在端口25上进行限制

您可能已经意识到这一点(我实际上并不认为这是一个问题),但是如果您尝试超过使用亚马逊时仍然适用的限制,Amazon EC2 会对通过端口25发送的电子邮件施加默认发送限制并限制出站连接SES,请参阅Amazon SES SMTP问题:

您是通过端口25从Amazon EC2实例发送到Amazon SES而您无法达到您的Amazon SES发送限制或者您正在接收超时 - Amazon SES EC2对通过端口25发送的电子邮件施加默认发送限制,并且如果您尝试,则限制出站连接超过这些限制.要删除这些限制,请提交删除电子邮件发送限制请求.您还可以通过端口465或端口587连接到Amazon SES,这两个端口都不受限制.

因此,我会删除测试/切换方案中的端口25并仅使用端口465/587以避免错误的线索(引用时您也可以请求删除此限制,但这将需要几个小时,端口25似乎最好避免在一开始) - 有点不幸的是,几个官方的Amazon SES样本正在使用端口25,甚至没有提到这个容易触发的问题.

  • 我有这个完全相同的问题,即使我在.Net 4上,我也不知道SmtpClient现在是一次性的.一旦我切换到使用声明,一切开始工作更顺畅.很好找! (3认同)
  • 感谢您的回复,我将切换到端口587.我同意它似乎是一个连接重置问题,但SmtpClient实际上不是2.0框架中的一次性.也许这就是问题,在这种情况下我需要找到一个解决方法. (2认同)
  • 不得不放弃亚马逊解决方案,因为我们无法及时开展工作.我将此标记为答案,因为我认为这些解决方案可能会解决其他人可能遇到的问题.Microsoft Exchange增加了他们的发送限制,因此我们使用它们 - 之前,它们设置得太低,这就是我们探索亚马逊选项的原因. (2认同)