Случайные проблемы с подключением к Amazon SES

Недавно я начал использовать Amazon SES. Моей первой попыткой было использовать порт 25, но у меня было много проблем с подключением. После некоторого поиска я обнаружил, что EC2 ограничивает трафик порта 25, чтобы избежать спама, поэтому я перешел на порт 587, но из примерно 1000 электронных писем в день примерно пять раз я получаю исключения SMTP-соединения в своем приложении.

Я считаю это случайным, потому что несколько неудачных писем находятся в разных частях приложения, и я не нашел между ними какой-либо закономерности.

Моя квота на отправку составляет 10000, а в электронных письмах менее 50 получателей. Это нормально, что иногда отправка не удается?

Заранее спасибо.

Я использую электронную почту Apache Commons версии 1.3.2 со следующими настройками:

setCharset("UTF-8");
setHostName("email-smtp.us-east-1.amazonaws.com");
setFrom("..."); // email from a verified domain
setAuthentication("...", "..."); // amazon smtp credentials
setSmtpPort(587);
setStartTLSEnabled(true);
setStartTLSRequired(true);

Исключения:

org.apache.commons.mail.EmailException: Sending the email to the following server failed : email-smtp.us-east-1.amazonaws.com:587
    at org.apache.commons.mail.Email.sendMimeMessage(Email.java:1410)
    at org.apache.commons.mail.Email.send(Email.java:1437)
    at br.com.spdata.email.HtmlEmail.send(HtmlEmail.java:136)
    at br.com.spdata.persistence.mysql.service.chat.AtendimentoService.doEnviarCopiaPorEmail(AtendimentoService.java:1112)
    at br.com.spdata.persistence.mysql.service.chat.AtendimentoService.access$000(AtendimentoService.java:62)
    at br.com.spdata.persistence.mysql.service.chat.AtendimentoService$1.run(AtendimentoService.java:1036)
    at java.lang.Thread.run(Thread.java:744)
Caused by: javax.mail.AuthenticationFailedException: [EOF]
    at com.sun.mail.smtp.SMTPTransport$Authenticator.authenticate(SMTPTransport.java:823)
    at com.sun.mail.smtp.SMTPTransport.authenticate(SMTPTransport.java:756)
    at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:673)
    at javax.mail.Service.connect(Service.java:317)
    at javax.mail.Service.connect(Service.java:176)
    at javax.mail.Service.connect(Service.java:125)
    at javax.mail.Transport.send0(Transport.java:194)
    at javax.mail.Transport.send(Transport.java:124)
    at org.apache.commons.mail.Email.sendMimeMessage(Email.java:1400)
    ... 6 more

|

java.lang.RuntimeException: org.apache.commons.mail.EmailException: Sending the email to the following server failed : email-smtp.us-east-1.amazonaws.com:587
    at br.com.spdata.jsf.util.JsfUtil.handleException(JsfUtil.java:236)
    at br.com.spdata.tecnico.page.agenda.AutorizacaoVisitaController.persist(AutorizacaoVisitaController.java:192)
    at sun.reflect.GeneratedMethodAccessor2446.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.apache.el.parser.AstValue.invoke(AstValue.java:278)
    at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:274)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:101)
    at javax.faces.component.UICommand.broadcast(UICommand.java:315)
    at javax.faces.component.UIData.broadcast(UIData.java:1106)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:786)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1251)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at br.com.spdata.tecnico.filter.ExceptionFilter.doFilter(ExceptionFilter.java:34)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61)
    at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
    at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
    at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
    at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
    at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
    at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
    at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
    at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
    at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)
    at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
    at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at com.googlecode.psiprobe.Tomcat70AgentValve.invoke(Tomcat70AgentValve.java:38)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)
Caused by: org.apache.commons.mail.EmailException: Sending the email to the following server failed : email-smtp.us-east-1.amazonaws.com:587
    at org.apache.commons.mail.Email.sendMimeMessage(Email.java:1410)
    at org.apache.commons.mail.Email.send(Email.java:1437)
    at br.com.spdata.email.HtmlEmail.send(HtmlEmail.java:136)
    at br.com.spdata.persistence.mysql.service.ScAgendaService.sendEmailConfirmacaoAgendamento(ScAgendaService.java:975)
    at br.com.spdata.tecnico.page.agenda.AutorizacaoVisitaController.persist(AutorizacaoVisitaController.java:168)
    ... 56 more
Caused by: javax.mail.MessagingException: Can't send command to SMTP host;
  nested exception is:
    java.net.SocketException: Connection closed by remote host
    at com.sun.mail.smtp.SMTPTransport.sendCommand(SMTPTransport.java:2163)
    at com.sun.mail.smtp.SMTPTransport.sendCommand(SMTPTransport.java:2150)
    at com.sun.mail.smtp.SMTPTransport.issueCommand(SMTPTransport.java:2074)
    at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.java:2111)
    at com.sun.mail.smtp.SMTPTransport.data(SMTPTransport.java:1887)
    at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1121)
    at javax.mail.Transport.send0(Transport.java:195)
    at javax.mail.Transport.send(Transport.java:124)
    at org.apache.commons.mail.Email.sendMimeMessage(Email.java:1400)
    ... 60 more
Caused by: java.net.SocketException: Connection closed by remote host
    at sun.security.ssl.SSLSocketImpl.checkWrite(SSLSocketImpl.java:1490)
    at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:70)
    at com.sun.mail.util.TraceOutputStream.write(TraceOutputStream.java:114)
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
    at com.sun.mail.smtp.SMTPTransport.sendCommand(SMTPTransport.java:2161)
    ... 68 more

|

org.apache.commons.mail.EmailException: Sending the email to the following server failed : email-smtp.us-east-1.amazonaws.com:587
    at org.apache.commons.mail.Email.sendMimeMessage(Email.java:1410)
    at org.apache.commons.mail.Email.send(Email.java:1437)
    at br.com.spdata.email.HtmlEmail.send(HtmlEmail.java:136)
    at br.com.spdata.persistence.mysql.service.chat.AtendimentoService.notificarChatSemAtendente(AtendimentoService.java:1541)
    at br.com.spdata.persistence.model.chat.AbstractAtendimentoBean.handleChatSemAtendente(AbstractAtendimentoBean.java:310)
    at br.com.spdata.persistence.model.chat.AbstractAtendimentoBean.entrar(AbstractAtendimentoBean.java:295)
    at br.com.spdata.cliente.page.atendimento.AtendimentoBean.entrar(AtendimentoBean.java:106)
    at sun.reflect.GeneratedMethodAccessor1416.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.apache.el.parser.AstValue.invoke(AstValue.java:278)
    at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:274)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:101)
    at javax.faces.component.UICommand.broadcast(UICommand.java:315)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:786)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1251)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at br.com.spdata.cliente.filter.ExceptionFilter.doFilter(ExceptionFilter.java:34)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at br.com.spdata.cliente.filter.LoginFilter.doFilter(LoginFilter.java:46)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at com.googlecode.psiprobe.Tomcat70AgentValve.invoke(Tomcat70AgentValve.java:38)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)
Caused by: javax.mail.MessagingException: Exception reading response;
  nested exception is:
    java.net.SocketException: Connection reset
    at com.sun.mail.smtp.SMTPTransport.readServerResponse(SMTPTransport.java:2210)
    at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1950)
    at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:642)
    at javax.mail.Service.connect(Service.java:317)
    at javax.mail.Service.connect(Service.java:176)
    at javax.mail.Service.connect(Service.java:125)
    at javax.mail.Transport.send0(Transport.java:194)
    at javax.mail.Transport.send(Transport.java:124)
    at org.apache.commons.mail.Email.sendMimeMessage(Email.java:1400)
    ... 50 more
Caused by: java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:196)
    at java.net.SocketInputStream.read(SocketInputStream.java:122)
    at com.sun.mail.util.TraceInputStream.read(TraceInputStream.java:110)
    at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:254)
    at com.sun.mail.util.LineInputStream.readLine(LineInputStream.java:89)
    at com.sun.mail.smtp.SMTPTransport.readServerResponse(SMTPTransport.java:2188)
    ... 58 more

person FkJ    schedule 02.12.2013    source источник


Ответы (2)


Вы должны убедиться, что вы не превышаете лимит отправки и скорость отправки — звучит так, как будто вы находитесь в пределах квоты отправки, но, возможно, вы превышаете разрешенную скорость отправки:

  • Квота на отправку — максимальное количество электронных писем, которое вы можете отправить за 24 часа. Квота отправки отражает скользящий период времени. Каждый раз, когда вы пытаетесь отправить электронное письмо, Amazon SES проверяет, сколько писем вы отправили за предыдущие 24 часа.

  • Максимальная частота отправки — максимальное количество электронных писем, которые вы можете отправить в секунду. Вы можете превысить этот предел для коротких вспышек, но не в течение длительного периода времени.

http://docs.aws.amazon.com/ses/latest/DeveloperGuide/manage-sending-limits.html

Кроме того, похоже, вы говорите, что иногда у вас есть 50 +/- получателей, перечисленных в одном электронном письме. AWS SES рекомендует, чтобы вы ограничивали свои электронные письма одним получателем.

http://docs.aws.amazon.com/ses/latest/DeveloperGuide/sending-email.html

person E.J. Brennan    schedule 13.12.2013
comment
Спасибо за ответ. Я редактировал свой вопрос так много раз, что забыл указать, что мое приложение отправляет около 2000 электронных писем в день, поэтому квота в порядке. Я согласен с одним получателем по электронной почте, но мне пришлось оптимизировать процесс, который отправляет до 1500 электронных писем последовательно. Согласно документации ограничение на количество получателей составляет 50, поэтому отправка пакетов по 50 значительно ускорила процесс. Я решил эти проблемы с подключением с помощью smtps, я напишу ответ, чтобы описать его лучше. - person FkJ; 17.12.2013

Решил проблему с помощью SMTPS с портом 465.

Электронная почта Commons, похоже, плохо обрабатывает SSL, поскольку isSSL всегда отображается как false в режиме отладки. Поэтому я переопределил метод отправки из HtmlEmail:

@Override
public String send() throws EmailException
{
    buildMimeMessage();

    // Implementação padrão de send() não conecta corretamente via SSL
    Transport transport = null;
    try
    {
        message.saveChanges();

        transport = getMailSession().getTransport("smtps");
        transport.connect("email-smtp.us-east-1.amazonaws.com", 465, <<amazon SMTP username>>, <<amazon SMTP pasword>>);
        transport.sendMessage(message, message.getAllRecipients());

        return message.getMessageID();
    }
    catch(MessagingException e)
    {
        throw new EmailException(e);
    }
    finally
    {
        if(transport != null)
        {
            try
            {
                transport.close();
            }
            catch(MessagingException e)
            {
                throw new EmailException(e);
            }
        }
    }
}
person FkJ    schedule 17.12.2013