是否可以接受将 java 邮件会话传输保持打开状态?

2022-09-02 22:22:17

我的应用程序需要临时发送电子邮件。我正在使用javamail的getDefaultSession和getTransport来发送消息,并且它都按预期工作。

但是,我注意到发送可能需要很长时间 - 每次发送最多七秒钟。如果我把台阶拆开,就像这样:

Transport transport = session.getTransport("smtp");
transport.connect();
transport.sendMessage( msg, addresses )
transport.close();

...我可以看到,这是连接()调用,几乎每次都需要花费所有时间。

我发现的所有示例都这样做 - 获取传输,连接,发送,断开连接。但是,当然,它们都是单次示例,或者在单个呼叫中发送大量电子邮件。

我想我可以保持连接打开,就像这样:

Transport transport = session.getTransport("smtp");
if (!transport.isConnected())
    transport.connect();
transport.sendMessage( msg, addresses )

(这里有一个变体:java邮件保持传输对象连接)。

我最终将不得不在某种关闭钩子中关闭它。我可能必须有一个回退(如果连接已经丢失,但传输没有意识到)。但是,有什么理由不在应用程序生存期内像这样保持打开状态呢?

谢谢 阿拉斯泰尔


答案 1

我真的没有看到保持单个SMTP连接打开的任何问题,并且建议使用传输对象进行连接重用(请参阅JavaMail教程)。

此外,我建议您在应用程序中只打开一个 smpt 连接(通过传输),将其保留在单个管理器实例中(即使用单例模式),从而避免为需要发送消息的每个组件保持不同连接打开的最终成本。


答案 2

根据(JavaMail的作者)在这里的答案:Javamail中的Threadsafety@Bill Shannon

由于传输表示与邮件服务器的连接,并且一次只有一个线程可以使用该连接,因此传输将同步来自多个线程的访问以保持线程安全,但您实际上只想从单个线程使用它。

因此,如果您计划从多个线程使用单个实例(现在通常是这种情况),从性能的角度来看,这实际上是一个非常糟糕的主意。使用 开发某种实例池可能会更好。TransportTransportThreadLocal


推荐