如何有效地使用javax.mail API发送批量邮件?我们可以使用重用经过身份验证的会话来提高速度吗?

Nar*_*dra 17 java email smtp jakarta-mail

我可以使用javax.mail API发送邮件.但这里的问题是平均每封邮件需要大约4.3秒才能发送到目的地.

如果我按顺序发送20封邮件,则需要大约86.599秒.根据我的要求,这种方法不起作用.我正在寻找一种可以在更短的时间内发送大量邮件的方法.

当我查看调试日志时,API正在尝试向SMTP服务器验证它发送的每条消息.但我只创建了一次会话,并为我发送的所有邮件使用相同的会话.现在我的问题是,每次向smtp服务器验证自身时,这不是一个开销过程.有没有更好的方法?

以下是您可能会发现有用的日志跟踪.

250-AUTH LOGIN PLAIN XOAUTH XOAUTH2
250 ENHANCEDSTATUSCODES
DEBUG SMTP: Found extension "SIZE", arg "35882577"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN XOAUTH XOAUTH2"
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Attempt to authenticate
DEBUG SMTP: check mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM 
DEBUG SMTP: AUTH LOGIN command trace suppressed
DEBUG SMTP: AUTH LOGIN succeeded
Run Code Online (Sandbox Code Playgroud)

请让我知道你对此的看法,对此的任何帮助都非常感谢.

-Narendra

Ian*_*rts 26

你是如何发送消息的?该JavaMail的常见问题表明,静态Transport.send方法将打开每封邮件建立新的连接,因为它是创建一个合适的便捷方法Transport的实例,将其连接,调用sendMessage,然后再次关闭连接.如果从中获得自己的Transport实例,则Session可以连接一次,然后sendMessage重复调用以在一个连接上发送多条消息,最后再发送一条消息close.某些事情(未经测试):

Transport t = session.getTransport();
t.connect();
try {
  for(Message m : messages) {
    m.saveChanges();
    t.sendMessage(m, m.getAllRecipients());
  }
} finally {
  t.close();
}
Run Code Online (Sandbox Code Playgroud)


Nic*_*rot 11

我在工作中得到了同样的要求.我必须发送批量电子邮件和独立电子邮件.我找不到简单而令人满意的答案:批量电子邮件可以使用单个连接发送,但独立电子邮件不能直到我创建异步缓冲来批量发送电子邮件.

最后但并非最不重要的是,Transport在短时间内使用大量连接可能会导致a,no more socket handles are available因为所有端口都卡在TIME_WAIT状态中.

我最后总结出最好的将是一个SMTP连接池,因为没有库(至少是免费的)用Apache Common Pool和Java Mail 创建了我的库:

//Declare the factory and the connection pool, usually at the application startup
SmtpConnectionPool smtpConnectionPool = new SmtpConnectionPool(SmtpConnectionFactoryBuilder.newSmtpBuilder().build());

//borrow an object in a try-with-resource statement or call `close` by yourself
try (ClosableSmtpConnection transport = smtpConnectionPool.borrowObject()) {
    MimeMessage mimeMessage = new MimeMessage(session);
    MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, false);
    mimeMessageHelper.addTo("to@example.com");
    mimeMessageHelper.setFrom("from@example.com");
    mimeMessageHelper.setSubject("Hi!");
    mimeMessageHelper.setText("Hello World!", false);
    transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
}

//Close the pool, usually when the application shutdown
smtpConnectionPool.close();
Run Code Online (Sandbox Code Playgroud)