Amazon SES прекращает работу

Я установил SAS Amazon, и он изначально работал в течение нескольких часов, а затем внезапно остановился. Все электронные письма, которые я отправляю как, и наш домен, были проверены. Мы не отправляем массовые электронные письма - всего несколько сотен в день. Всякий раз, когда я вношу изменения в 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="[email protected]">
      <network defaultCredentials="false" host="email-smtp.us-east-1.amazonaws.com" userName="***" password="***" port="587" />
    </smtp>
  </mailSettings>
</system.net>

С# code:

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)

Я попытался получить помощь на форумах Amazon, но мне не повезло. Кажется, что что-то мешает подключению, но я не знаю, что. Есть идеи? Спасибо.

Ответ 1

Это похоже на сложную проблему - я не на 100% позитивен в этом, но вы, похоже, пропустите удаление клиента SMTP, о котором упоминается в Отправка электронной почты часто бывает очень медленно после перехода на экземпляр VPC, чтобы вызвать ту самую ошибку, которую вы видите:

Когда я не распоряжаюсь SmtpClient, я получаю ошибку...

'Сервис недоступен, закрывая канал передачи. Сервер ответ был: Тайм-аут ожидания данных от клиента.

Это действительно хорошее объяснение прерывистых проблем, т.е. в зависимости от исполняемого кодового пути эта проблема может инициировать подключение SMTP к Amazon SES для зависания, который, очевидно, исправляется путем переключения на другой порт, подразумевая, что соединение reset - то, что SmtpClient.Dispose Method обеспечивает а также:

Отправляет сообщение QUIT на SMTP-сервер, изящно завершая 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
    (
              "[email protected]",  // Replace with the sender address.
              "[email protected]",    // 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.

Удачи!


Добавление

Регулирование Amazon EC2 на порте 25

Вероятно, вы знаете об этом (и я на самом деле не думаю, что это проблема здесь), но Amazon EC2 устанавливает пределы отправки по умолчанию по электронной почте, отправленной через порт 25, и отключает исходящие соединения, если вы пытаетесь превысить те ограничения, которые по-прежнему применяются при использовании Amazon SES, см. Проблемы SMTP Amazon SES:

Вы отправляете на ASAS Amazon из экземпляра Amazon EC2 через порт 25 и вы не можете достичь своих пределов отправки Amazon SES, или вы время ожидания выхода - Amazon SES EC2 налагает ограничения отправки по умолчанию на адрес электронной почты, отправленный через порт 25, и отключает исходящие соединения, если вы попытаться превзойти эти пределы. Чтобы удалить эти ограничения, отправьте Запрос на удаление ограничений отправки электронной почты. Вы также можете подключиться к Amazon SES через порт 465 или порт 587, ни один из которых не дросселируется.

Следовательно, я бы удалил порт 25 из вашего сценария тестирования/переключения и использовал только порты 465/587, чтобы избежать ложных отведений (как указано, вы также можете запросить удаление этого ограничения, хотя оно будет несколько часов и порт 25, по-видимому, лучше всего избегать в первую очередь). Это немного неудачно, что некоторые официальные образцы SES Amazon используют порт 25, даже не упомянув об этой легко вызванной проблеме.

Ответ 2

Хотя этот вопрос специфичен для .NET v2.0, я недавно столкнулся с этой проблемой и с .NET v4.5. Даже после добавления использования клиента SMTP (как было предложено в более ранних сообщениях), я все еще периодически получал эту ошибку. После многих часов исследований я получил поддержку AWS для порта STARTTLS (2587; http://docs.aws.amazon.com/ses/latest/DeveloperGuide/smtp-connect.html), и в очень мелкой печати Microsoft заявляет, когда "EnableSsl" является истинным для клиента SMTP, клиент ожидает сеанс STARTTLS (https://msdn.microsoft.com/en-us/library/system.net.mail.smtpclient.enablessl(v=vs.110).aspx). Таким образом, после обновления моего порта до 2587 и окружения SmtpClient в "using {}" я смог успешно отправить ~ 20k электронных писем без воспроизведения ошибки.

Таким образом, рабочая конфигурация будет:

<system.net>
  <mailSettings>
    <smtp deliveryMethod="Network">
      <network host="email-smtp.us-west-2.amazonaws.com" port="2587" enableSsl="true" password="password" />
    </smtp>
  </mailSettings>
</system.net>

Один отказ от ответственности заключается в том, что я до сих пор не полностью понимаю истинную конфигурацию либо AWS, либо .NET SMTP-клиента, поэтому это все еще немного обстоятельно.

Ответ 3

Я также использую сервис AWS ses

 smtp deliveryMethod="Network" from="[email protected]"
    network enableSsl="true" host="email-smtp.us-east-1.amazonaws.com" userName="******" password="*********" port="25" 
 smtp

Надеюсь, это сработает для вас.