JavaMail的大坑

關於郵箱的坑,不妨先看一篇幽默的文章(=^ ◡ ^=):救命!我的電子郵件發不到 500 英里以外!

問題背景

一般使用JavaMail發送郵件大致過程如下,創建同郵件服務的Session,配置Session參數等:

// Common variables
String host = "your_smtp_server";
String from = "from_address";
String to = "to_address";

// Set properties
Properties props = new Properties();
props.put("mail.smtp.host", host);
props.put("mail.debug", "true");
 
// Get session
Session session = Session.getInstance(props);
 
try {
    // Instantiate a message
    Message msg = new MimeMessage(session);
 
    // Set the FROM message
    msg.setFrom(new InternetAddress(from));
 
    // The recipients can be more than one so we use an array but you can
    // use 'new InternetAddress(to)' for only one address.
    InternetAddress[] address = {new InternetAddress(to)};
    msg.setRecipients(Message.RecipientType.TO, address);
 
    // Set the message subject and date we sent it.
    msg.setSubject("Email from JavaMail test");
    msg.setSentDate(new Date());
 
    // Set message content
    msg.setText("This is the text for this simple demo using JavaMail.");
 
    // Send the message
    Transport.send(msg);
}
catch (MessagingException mex) {
    mex.printStackTrace();
}

本以爲這樣就可以愉快地發郵件了。
運行一段時間發現系統總是卡在郵箱發送模塊。後來查閱資料發現裏面的大坑。

被忽略的參數

關鍵參數

參數 類型 解釋
mail.smtp.connectiontimeout int Socket connection timeout value in milliseconds. This timeout is implemented by java.net.Socket. Default is infinite timeout.
mail.smtp.timeout int Socket read timeout value in milliseconds. This timeout is implemented by java.net.Socket. Default is infinite timeout.
mail.smtp.writetimeout int Socket write timeout value in milliseconds. This timeout is implemented by using a java.util.concurrent.ScheduledExecutorService per connection that schedules a thread to close the socket if the timeout expires. Thus, the overhead of using this timeout is one thread per connection. Default is infinite timeout.

解析
*注意加粗部分,翻譯過來就是“默認時間無窮大”,總之一句話:你要不配置這幾個參數,郵箱發送的等待時間可能是無窮大,出現異常後(比如郵箱服務器繁忙)客戶端有可能永遠在等待往服務器讀寫消息。這裏涉及到跟服務器間的socket交互。*如下圖,JavaMail在socket讀寫過程中有可能無限等待下去
這裏寫圖片描述

解決方法

把JavaMail重構成異步,避免阻塞核心業務邏輯。
爲JavaMail設置超時時間


		Properties props = new Properties();
		props.put("mail.smtp.timeout", 10000);
		props.put("mail.smtp.connectiontimeout", 10000);
		props.put("mail.smtp.writetimeout", 10000);
        props.put("mail.smtp.host", host);
        props.put("mail.debug", "true");
       // Get session
        Session session = Session.getInstance(props);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章