Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用java mail发送大量电子邮件花费的时间太长_Java_Email_Smtp_Jakarta Mail - Fatal编程技术网

使用java mail发送大量电子邮件花费的时间太长

使用java mail发送大量电子邮件花费的时间太长,java,email,smtp,jakarta-mail,Java,Email,Smtp,Jakarta Mail,我必须了解以下情况。我想用java邮件客户端发送大量电子邮件。这意味着我想一次发很多电子邮件。将它们全部放在收件人字段中的意见是毫无疑问的,因为没有收件人必须看到对方(密件抄送不起作用,因为您仍然可以看到收件人)。 因此,我要做的是,打开一个新的Transport连接,对每个收件人使用sendMessage(),然后关闭Transport连接。以下是代码片段: Session session = Session.getInstance(smtpProps, new javax.mail.Auth

我必须了解以下情况。我想用java邮件客户端发送大量电子邮件。这意味着我想一次发很多电子邮件。将它们全部放在收件人字段中的意见是毫无疑问的,因为没有收件人必须看到对方(密件抄送不起作用,因为您仍然可以看到收件人)。 因此,我要做的是,打开一个新的
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
类的抽象方法,因此在我的示例中使用了
com.sun.mail.smtp
中的
SMTPTransport

我的问题没有:在
transport.connect()
上的连接时间大约需要5秒,在
sendmages
上的发送时间也需要5秒。这意味着,如果我向10个收件人发送电子邮件,需要5+(10*5)=~55秒。这是很长的一段时间,想想我们有1000个接受者

这正常吗?或者,你知道是什么导致了这个问题,它持续了这么长时间吗?是否有其他(好的)
sendMessage()
实现,或者该方法的默认用法是
SMTPTransport

信息:
for循环分别在单独的线程中运行,因此电子邮件在后台发送。整个servlet包含这个被剪断的部分,它运行在服务器集群上的docker容器中。因此,如果我将其并行化,或者使用多个线程,我不知道该行为如何与集群上的其他servlet一致。

而不是使用:

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

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

我想我找到了解决问题的方法。 连接花费如此多的时间似乎是正常的。 我的问题是,附件必须每次上传到smtp服务器,大约4秒。对于整个请求,每次上传都会占用大量时间。
因此,如果不发送附件,请求不会花费太多时间。因此,在我的实现中没有问题,而不是每次都上传附件。

您尝试过将其并行化吗?我知道这是一个带有一些参数的完整方法,例如
authUser
authPass
以及电子邮件正文
eml
(?)似乎很容易做到。只需尝试从线程池执行器或使用java 8
parallelStream()
lambda调用此方法。这里有很多例子,事实上,你可以尝试用一个
parallelStream()
来更改
for
循环,这应该可以做到。@Marc:是的,这只是从一个更大的方法中剪下来的。这个循环已经在一个单独的线程中运行,因此电子邮件是在后台发送的。整个servlet在集群中的docker容器中运行。我不知道与其他servlet一致的行为是如何发生的,如果我有很多线程,这可能会导致问题,我不清楚。我用这些信息展开我的问题。DNS查找可能会影响某些计算机上的性能。为
mail.smtp.localhost
设置会话属性,以防止在
HELO
命令上查找名称。设置
mail.from
mail.host
(不是协议版本)的会话属性,因为这将阻止在
MimeMessage.updateMessageID()上查找名称。您看到了吗?不,我看不到。请阅读我的整个问题,而不仅仅是代码部分。请阅读第四句,然后你知道为什么你的答案不是我问题的答案。你应该考虑更大的问题,比如如果你真的需要上传或下载一个大的eml文件怎么办?