解決項目遷移到阿里雲後發送不了郵件的問題

最近把項目遷移到阿里雲,這幾天觀察後臺日誌,發現這麼一段異常:

2020-04-09 20:51:39 ERROR MailUtils:228 : 發送郵件失敗!com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp.163.com, 25; timeout -1;
  nested exception is:
	java.net.ConnectException: Connection timed out (Connection timed out)

然後去調發送郵件的接口,還真的發不了。剛開始也是覺得很奇怪,之前項目在另一臺服務器上運行好好的,在本地也可以正常的,爲什麼一遷移到阿里雲服務器上就不行了呢?在阿里雲官網上提交工單,他們的售後工程師說了一堆,爲了防止垃圾郵件的泛濫,阿里加入了中國什麼反垃圾郵件協會,禁用25端口。並給出兩種解決方案:

其一:使用SSL安全端口465發送,

其二,使用他們阿里郵箱,他們將25重定向到80端口了。

果斷排除第二種,這一來嘛,公司買了第三方郵箱的服務,未到期,重新買阿里郵箱,會造成資源浪費,這二來嘛,還需要修改各個項目涉及到郵件發送的代碼。除了核心業務方面的代碼,基礎配置的代碼我一向懶得去改。

所以就毅然決然踏上使用465端口這條路。首先找到項目中郵件發送的代碼,可找來找去,沒發現涉及到端口方面的配置,於是聯繫郵件服務提供方,他們說已經開放465端口了的,不信,你用下面的命令測試一下就知道了:

telnet smtp.163.com 465

打開終端,輸入以上命令,確實出來welcome的歡迎語。那說明問題不在他們那,於是又找到阿里,阿里小姐姐可真敬業啊,大中午我在吃着午飯,她打來電話,此時已過北京時間12:30。電話裏態度也是很好,說了一大堆,掛了電話一想,她話中“是,郵件提供方開放了465端口,但不代表他就使用默認的465端口來發郵件啊,萬一他使用25呢”是解決問題的中心思想呀。又聯繫郵件服務提供方,他們明確告訴我,他們並不能指定使用哪個端口來發送郵件,使用哪個端口發送郵件在於客戶端的設定。轉了幾圈,才猛地發現,原來需要自己編碼手動指定郵件發送所使用的端口,如果不指定端口,那麼系統將會使用25端口來發送。於是進行編碼和測試,終於通了。下面是實現的源碼:

/**
 * 使用SSL 465安全方式發送
 * @param toEmail 收件人郵箱
 * @param content 郵件內容
 * @param subject 郵件主題
 */
public static void sendSSLEmail(String toEmail, String content, String subject) {
	boolean isSSL = true;
	String host = "smtp.163.com";
	int port = 465;
	final String from = "[email protected]"; // 發件人的email
	boolean isAuth = true;
	final String password = "123456";

	Properties props = new Properties();
	props.put("mail.smtp.ssl.enable", isSSL); //指定使用SSL方式發送
	props.put("mail.smtp.host", host);        //郵件主機
	props.put("mail.smtp.port", port);       //指定使用465安全端口
	props.put("mail.smtp.auth", isAuth);     //需要驗證

	Session session = Session.getDefaultInstance(props, new Authenticator() {
	
	/**
	 * 身份驗證
	 */
	@Override
	protected PasswordAuthentication getPasswordAuthentication() {
		return new PasswordAuthentication(from , password);
	}
	});
	
	/**
	 * 實現郵件發送功能
	 */
	try {
		Message message = new MimeMessage(session);
		message.setFrom(new InternetAddress(from));
		message.addRecipient(Message.RecipientType.TO, new InternetAddress(toEmail));
		message.setSubject(subject);
		message.setText(content);
		LOGGER.info("準備發送");
		Transport.send(message);
		LOGGER.info("發送完畢");
	} catch (AddressException e) {
		LOGGER.error(e.getMessage(),e);
	} catch (MessagingException e) {
		LOGGER.error(e.getMessage(),e);
	}

}

注:文中涉及到賬號密碼請替換爲自己的信息。

更新到服務器終於能正常發送郵件了。 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章