目前我们发送电子邮件消息的代码是这样的:
@Override
public SendEmailResponse sendEmail(DtoEmailMessage dtoEmailMessage) {
try {
MimeMessage mimeMessage = mimeMessageCreator.createMessage(dtoEmailMessage);
javaMailSender.send(mimeMessage);
return SendEmailResponse.ok(channelEmailMessage.getEmailNotification().getTo(), mimeMessage.getMessageID());
} catch (UnsupportedEncodingException | MessagingException | RuntimeException e) {
...
}
}
哪里需要改进?
我想支持一个保留的smtp服务器列表。如果server_1我想尝试使用server_2. 如果server_2is failed -server_3
我知道spring-retry
和spring-hystrix
,但看起来它们不适用于当前的任务。
是否有任何生产准备的解决方案为我的任务,或者它是更好的实现我自己?
最好处理由负载均衡器管理的多个SMTP主机,但是您也可以在应用程序代码中管理。
public class EmailService {
private static final int MAX_RETRIES = 3;
private final List<String> smtpServers;
public EmailService(List<String> smtpServers) {
this.smtpServers = smtpServers;
}
@Override
public SendEmailResponse sendEmail(DtoEmailMessage dtoEmailMessage) {
for (String smtpServer : smtpServers) {
try {
// create the email message
MimeMessage mimeMessage = mimeMessageCreator.createMessage(dtoEmailMessage);
JavaMailSenderImpl mailSender = new JavaMailSenderImpl()
mailSender.setHostName(smtpServer);
mailSender.setPort(587);
mailSender.setUsername("myusername");
mailSender.setPassword("mypassword");
// send the email message with automatic retry
RetryExecutor executor = new RetryExecutor()
.withMaxRetries(MAX_RETRIES)
.withWaitStrategy(WaitStrategies.fixedWait(1, TimeUnit.SECONDS));
executor.retry(() -> mailSender.send(mimeMessage));
return SendEmailResponse.ok(channelEmailMessage.getEmailNotification().getTo(), mimeMessage.getMessageID());
} catch (EmailException e) {
// log the error and try the next SMTP server
}
}
// all SMTP servers failed
throw new RuntimeException("Failed to send email message to any SMTP server");
}
}
对于我来说,你必须实现断路器的设计模式。
我建议使用
Hystrix已不支持,已弃用
最好使用具有所有池功能的SMTP连接池(https://github.com/nithril/smtp-connection-pool)。