事件回顾到某天下班,然后听到手机消息,来自企业微信,是财务小姐姐向我发来了问候,问我为什么邮件突然就发不出去了。
我也愣住了,这个功能是去年做的了,一直没有什么问题,甚至另一个系统也是copy我的代码过去,一直流畅运行。我立马打开电脑,开始看日志。Could not connect to SMTP host:smtp.exmail.qq.com,port:465,这是我第一眼的看到的问题,要是知道后面的结果,我肯定会悔不当初。
一开始我以为是服务器连不上了,然后我开始百度,找了很多问题,试着改端口,587之类的。因为我们通过企业邮箱,账号通过企业微信账号申请,服务并不是qq服务器,所以走的465端口。然后改了很多版的代码,在灰度环境进行测试,奇了个大怪,都不行。然后发现有一方法通过修改jdk中某个文件,去掉 TLSv1协议,但是我们线上都是走的k8s。这个就不好进行修改。
解决无果,我就只能先说这个要等明天才能处理。第二天去了公司,就去问了哈运维可能是什么问题,运维说他们换了底包,我就想到可能是这个问题,但是很奇怪,把底包换了回来,依然是这个错误,然后我说把灰度环境回滚到几天前,因为几天前环境肯定是正确的把,然后回滚了依然不行,我都裂开了。几经折腾还是没有解决。这时候我就开始向上级汇报问题,上级又向架构师汇报问题,然后架构师说把错误堆栈日志发给他,然后我就在看他如何解决问题,我首先说了我的想法,然后他开始说你不能直接看TCP连接问题,他直接定位到jdk版本问题,然后他也百度,只是百度的这个NO appropriate protocol,当时我也百度了这个,多数都是说的数据库链接问题,我就没把主要问题放到这上面,随后架构师向我发来了解决办法,最终通过指定协议解决问题,如果能在jdk删除了那个TLSv1协议,我认为也能解决这个问题。
核心解决代码:
props.put(“mail.smtp.ssl.protocols”, “TLSv1.2”);
public static Session getMailSession() throws GeneralSecurityException {
Properties props = new Properties();
// 开启debug调试
// props.setProperty("mail.debug", "true");
// 发送服务器需要身份验证
props.setProperty("mail.smtp.auth", "true");
// 设置邮件服务器主机名 qq
// props.setProperty("mail.host", "smtp.qq.com");
// 设置企业微信邮件服务器 企业邮箱
props.setProperty("mail.smtp.host", "smtp.exmail.qq.com");
// 设置企业微信邮件服务器端口
props.setProperty("mail.smtp.port", "465");
// 发送邮件协议名称
props.setProperty("mail.transport.protocol", "smtp");
// props.put("mail.smtp.starttls.required", "true");
props.put("mail.smtp.ssl.protocols", "TLSv1.2");
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
props.put("mail.smtp.ssl.enable", "true");
props.put("mail.smtp.ssl.socketFactory", sf);
Session session = Session.getInstance(props);
return session;
}