使用java邮件发送bulkemails需要太长时间

时间:2017-05-11 10:50:56

标签: java email smtp javamail

我必须遵循以下情况。我想用java邮件客户端发送批量电子邮件。这意味着我想一次发送大量电子邮件。将它们全部放在收件人字段中的意见是不可能的,因为没有收件人必须互相看到(bcc不起作用,因为你仍然看到收件人)。 所以我要做的是,打开一个新的Transport连接,为每个收件人使用sendMessage(),然后关闭Transport连接。以下是代码段:

Session session = Session.getInstance(smtpProps, new javax.mail.Authenticator() {
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(authUser, authPass);
    }
});

InputStream is = IOUtils.toInputStream(eml, "UTF-8");
MimeMessage message = new MimeMessage(session, is);

Transport transport = session.getTransport("smtp");
transport.connect(smtpServer, smtpPort, smtpUser, smtpPass);

Address[] recipients = message.getRecipients(RecipientType.TO);
for(Address address : recipients) {
    message.setRecipient(RecipientType.TO, address);
    transport.sendMessage(message, new Address[]{ address });
}
transport.close();

请记住,sendMessage()方法是javax.mail.Transport类的抽象方法,因此在我的案例中使用了来自SMTPTransport的{​​{1}}的实现。

否我的问题:com.sun.mail.smtp的连接时间大约需要5秒,发送时间也是transport.connect()。这意味着,如果我向例如10个收件人发送电子邮件,则需要5 +(10 * 5)= ~55秒。这很长,考虑一下我们有1000名收件人。

这是正常的吗?或者您是否知道可能导致问题的原因,这需要很长时间?是否有其他(好的)sendMessage实现,或sendMessage()此方法的默认用法?

信息:
for循环,这个代码剪切分别在一个单独的线程中运行,因此电子邮件是在后台发送的。并且包含此剪辑的整个servlet在servercluster上的docker-container中运行。因此,如果我将其并行化,或者使用多个线程,我就不知道该行为是如何与该群集上的其他servlet一致的。

2 个答案:

答案 0 :(得分:0)

我想我找到了解决问题的方法。 连接花费这么多时间似乎是正常的。 我的问题是,附件必须每次上传到smtp-server,大约4秒钟。每次上传总计达到整个请求的大量时间。 因此,如果不发送附件,请求就不会花费太多时间。所以我的实现没有问题,而不是每次都上传附件。

答案 1 :(得分:-1)

而不是使用:

Address[] recipients = message.getRecipients(RecipientType.TO);
for(Address address : recipients) {
    message.setRecipient(RecipientType.TO, address);
    transport.sendMessage(message, new Address[]{ address });
}

您应该使用:

Address[] recipients = message.getRecipients(RecipientType.TO);
message.addRecipients(RecipientType.CC, recipients);

这将向邮件服务器发送单个请求以获取邮件,并将节省大量时间和请求。