在配置JavaMail时,总是有一种有趣的方法。 基本上,您必须填写无类型的地图或属性结构,并希望获得正确的解释。 网络上无数的教程显示了使其正常工作(发送/接收邮件)所需的最小属性。
但是,正如我们痛苦地了解到的那样,您可能需要注意一些鲜为人知的属性,即套接字IO的超时设置。 默认情况下,JavaMail对所有套接字操作(连接,IO等)都使用无限超时!
现在,假设您有一簇SMTP服务器,它们可以处理通过DNS循环访问的传出邮件。 如果其中一台服务器发生故障(恰好是JavaMail想要连接的服务器),则您的邮件发送线程将永远挂起! 这正是发生在我们身上的事情,我们需要表演一些真正令人讨厌的魔术来避免悲剧。
因此,我们现在为所有操作设置超时:
String MAIL_SMTP_CONNECTIONTIMEOUT ="mail.smtp.connectiontimeout";String MAIL_SMTP_TIMEOUT = "mail.smtp.timeout";String MAIL_SMTP_WRITETIMEOUT = "mail.smtp.writetimeout";String MAIL_SOCKET_TIMEOUT = "60000"; // Set a fixed timeout of 60s for all operations - // the default timeout is "infinite"props.put(MAIL_SMTP_CONNECTIONTIMEOUT, MAIL_SOCKET_TIMEOUT);props.put(MAIL_SMTP_TIMEOUT, MAIL_SOCKET_TIMEOUT);props.put(MAIL_SMTP_WRITETIMEOUT, MAIL_SOCKET_TIMEOUT);
另外,如果您打算访问基于DNS的循环服务(例如Amazon S3)或在我们的示例中的邮件集群,请不要忘记配置Java的DNS缓存tiemout(默认情况下也是无限的):
// Only cache DNS lookups for 10 seconds java.security.Security.setProperty("networkaddress.cache.ttl","10");
而且,在我们看来,将所有编码设置为UTF-8(独立于底层操作系统)对我们来说是一个好主意,以提供稳定的环境:
System.setProperty("file.encoding", Charsets.UTF_8.name());
System.setProperty("mail.mime.charset", Charsets.UTF_8.name());
…您根本不想关心这样的事情吗? 随意使用我们的开源Java库SIRIUS ,它通过提供简洁的fluet API发送邮件来处理所有这些工作: GitHub上的Sources 。
可以在集群管理器中找到一个用法示例:
@Partprivate MailService ms;private void alertClusterFailure() {...ms.createEmail().useMailTemplate("system-alert", ctx).toEmail(receiver).send();...}
翻译自: https://www.javacodegeeks.com/2014/06/javamail-can-be-evil-and-force-you-to-restart-your-app-server.html