如何有效地利用javax.mail API发送大量的邮件? &我们可以使用复用认证的会议,以提高

2019-07-03 16:16发布

我能够发送使用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

请让我知道你对这个想法并在此任何帮助非常感谢。

-Narendra

Answer 1:

你是如何发送短信? 该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();
}


Answer 2:

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

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

我终于得出结论:最好的将是一个SMTP连接池,因为没有图书馆存在(至少免费) 我矿创建使用Apache公共池塘和Java邮件:

//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();


Answer 3:

不知道如果标准Java邮件API允许你想什么来完成(会话重用),但你可以考虑使用多线程:

我会用一个线程池,并提交邮件发送作业吧。 然后,你做的工作类的代码,它是由线程池异步执行中的任何错误处理/重发,和你的主线程可以继续做其他的事情。 提交作业只需要毫秒。 这一段时间,因为我实现了在Java线程池的东西,但我记得那是相当容易和简单。 如果谷歌的“Java线程池”你会发现很多的材料。



Answer 4:

您可以使用线程池,因为它提供了很好的performance.I实现并分享你下面的代码片段。

try  {
    ExecutorService executor = Executors.newFixedThreadPool("no. of threads"); // no. of threads is depend on your cpu/memory usage it's better to test with diff. no. of threads.
    Runnable worker = new MyRunnable(message); // message is the javax.mail.Message
    executor.execute(worker);
    executor.shutdown();
    executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
}


文章来源: How to Send bulk mails using javax.mail API efficiently? & Can we use reuse authenticated sessions to improve speed?