MimeMessage.saveChanges 真的很慢 [英] MimeMessage.saveChanges is really slow

查看:45
本文介绍了MimeMessage.saveChanges 真的很慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于包含 m.saveChanges(),以下测试大约需要 5 秒才能执行.

The following test is taking around 5 seconds to execute due to the inclusion of m.saveChanges().

import org.junit.Before;
import org.junit.Test;    
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;
import java.io.IOException;
import java.util.Properties;
import static org.junit.Assert.assertEquals;   
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@Test
public void test1() throws MessagingException, IOException {
    Session s = Session.getDefaultInstance(new Properties());
    MimeMessage m = new MimeMessage(s);
    m.setContent("<b>Hello</b>", "text/html; charset=utf-8");
    m.saveChanges();
    assertEquals(m.getContent(), "<b>Hello</b>");
    assertEquals(m.getContentType(), "text/html; charset=utf-8");
}

我也用 mockito 嘲笑了 Session,但它没有帮助:

I have also mocked the Session with mockito but it doesn't help:

Session s = mock(Session.class);
when(s.getProperties()).thenReturn(new Properties());

这里有什么问题?我可以模拟什么来加快速度?

What is the problem here? What can I mock to speed things up?

推荐答案

修复最常见的错误人们首先在您的代码中使用 JavaMail 时.

DNS 查找 可能会影响某些机器的性能.对于 JDK,您可以更改缓存 DNS 查找的安全属性 networkaddress.cache.ttlnetworkaddress.cache.negative.ttl 或设置系统属性 sun.net.inetaddr.ttlsun.net.inetaddr.negative.ttl.JDK 7 及更高版本中的默认行为在缓存方面做得很好,因此您不必更改这些设置.

DNS lookup can hurt performance on some machines. For the JDK you can change the security properties for caching DNS lookup networkaddress.cache.ttl and networkaddress.cache.negative.ttl or set the system properties sun.net.inetaddr.ttl and sun.net.inetaddr.negative.ttl. The default behavior in JDK 7 and later does a good job of caching so you shouldn't have to change these settings.

最好使用会话属性来避免某些此类查找.

Preferably, you can use the session properties to avoid some these lookups.

  1. mail.from 设置会话属性mail.host(不是协议版本),因为这会阻止在 InternetAddress.getLocalAddress(Session).调用 MimeMessage.saveChanges(), MimeMessage.updateHeaders(), MimeMessage.updateMessageID(),或 MimeMessage.setFrom() 将触发调用以获取本地地址.如果未设置上述属性,则此方法将尝试查询主机名.通过设置属性,此方法将从会话中提取主机名字符串,而不是尝试昂贵的 DNS 查找.
  2. 设置会话属性mail.smtp.localhostmail.smtps.localhost 以防止在 HELO 命令上查找名称.
  3. mail.smtp.frommail.smtps.from 以防止查找 EHLO 命令.
  4. 或者,您可以设置系统属性 mail.mime.address.usecanonicalhostnamefalse 如果您的代码依赖于 setFrom() 但是如果您应用了点,这将被处理#1.
  5. 对于IMAP,您可以尝试设置mail.imap.sasl.usecanonicalhostnamemail.imaps.sasl.usecanonicalhostnamefalse 这是默认值.
  1. Set session property for mail.from or mail.host (not the protocol versions) as that will prevent the name lookup on InternetAddress.getLocalAddress(Session). Calling MimeMessage.saveChanges(), MimeMessage.updateHeaders(), MimeMessage.updateMessageID(), or MimeMessage.setFrom() will trigger a call to get the local address. If the above properties are not set then this method will attempt to query for the host name. By setting the properties, this method will pull the host name string from the session instead of attempting the expensive DNS lookup.
  2. Set the session property for mail.smtp.localhost or mail.smtps.localhost to prevent name lookup on the HELO command.
  3. Set session property for mail.smtp.from or mail.smtps.from to prevent lookup on EHLO command.
  4. Alternatively, you can set the system property mail.mime.address.usecanonicalhostname to falseif your code is relying on the setFrom() but this will be handled if you applied point #1.
  5. For IMAP, you can try to set mail.imap.sasl.usecanonicalhostname or mail.imaps.sasl.usecanonicalhostname to false which is the default value.

由于您不传输消息,请将代码更改为:

Since your are not transporting a message, apply rule #1 by changing your code to:

@Test
public void test1() throws MessagingException, IOException {
    Properties props = new Properties();
    props.put("mail.host", "localhost"); //Or use IP.
    Session s = Session.getInstance(props);
    MimeMessage m = new MimeMessage(s);
    m.setContent("<b>Hello</b>", "text/html; charset=utf-8");
    m.saveChanges();
    assertEquals(m.getContent(), "<b>Hello</b>");
    assertEquals(m.getContentType(), "text/html; charset=utf-8");
}

如果您正在传输消息,则组合规则 #1、#2 和 #3,这将阻止访问主机系统进行名称查找.如果您想在传输过程中阻止所有 DNS 查找,则必须使用 IP 地址.

If you are transporting a message then combine the rules #1, #2, and #3 which will prevent accessing the host system for a name lookup. If you want to prevent all DNS lookups during a transport then you have to use IP addresses.

这篇关于MimeMessage.saveChanges 真的很慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆