【问题标题】:What is the best approach for sending emails in java with out blocking main code flow?在不阻塞主要代码流的情况下,在 java 中发送电子邮件的最佳方法是什么?
【发布时间】:2017-09-18 04:00:29
【问题描述】:

我的服务器需要非常频繁地发送电子邮件。电子邮件很重;他们有附件以及内联图像。

我当前的代码在发送电子邮件之前会阻止代码。 (每封电子邮件会浪费 5 到 6 秒)

在不阻塞主要代码流的情况下处理电子邮件的最佳方法是什么?

如果您建议线程,请详细说明它的处理效率如何?

【问题讨论】:

  • 高效意味着什么?它只能由单线程处理。为邮件添加一个额外的线程就是这样。这是每个人都遵循的通用方法。
  • 线程始终是在不阻塞主线程的情况下执行繁重进程的解决方案。这将与您的代码一样高效...如果您一次要发送超过 1 封邮件,使用多个线程(不要使用无限量)。但没有比这更完整的答案了。如果需要,请阅读有关线程的指南
  • 请提供更多信息。您使用的是 Spring、Java EE 还是其他框架?你使用 java Mail API 还是其他库?
  • 我使用 java 邮件 API 和 Java EE。

标签: java multithreading email


【解决方案1】:

如果您为必须发送的每封电子邮件生成一个线程,您就可以有效地做到这一点。

一种方法如下:


你需要一个纯粹是 Thread 扩展的类:

public class MailSenderThread extends Thread {        
    @Override
    public void run() {
        try {
            // Code to send email
        } catch (Exception ex) {
            ex.printStackTrace();
        }    
    }    
}

当你想发送电子邮件时,你可以这样做:

new MailSenderThread().start();

这是我能想到的最短/最简单的方法。


您也可以参考an example in my public repository。题外话,但它得到了概念。

【讨论】:

    【解决方案2】:

    有多种方法可以实现此功能。

    同步调用

    这是您已经在使用的。代码(同步)调用 Java Mail API 并等待 API 完成执行。该过程可能需要一些时间,具体取决于构建电子邮件消息的复杂性(从数据库中获取记录、读取图像/文档(附件)、与邮件服务器通信等)。

    权衡

    1. 对于单个请求(网络/桌面),响应延迟将根据构建和发送电子邮件所需的时间而增加。
    2. 发送电子邮件时出现异常,可能需要重做整个过程(如果重试)。
    3. 由于发送电子邮件时出现异常,事务数据(例如 DB)可能会回滚。这可能不是我们想要的行为。
    4. 如果多个用户同时调用类似的功能,整体应用程序延迟将会增加。
    5. 如果电子邮件发送代码与其他功能代码紧密耦合,则可能无法使用电子邮件重试功能。

    多线程方法

    创建一个单独的线程来异步发送电子邮件。调用代码不必等待电子邮件发送功能完成并执行其余代码。理想情况下,应该使用 ThreadPool,而不是平淡地创建新线程。

    权衡

    1. 虽然请求延迟会下降,但仍然不可靠。构建/发送电子邮件时发生的任何异常都可能导致没有电子邮件发送给用户。

    2. 电子邮件发送功能不能分布在多台机器上。

    3. 重试功能是可能的,因为电子邮件代码被分成单独的类。这个类可以独立调用,不需要重做其他事情。

    异步处理

    创建一个类,该类接受电子邮件请求并将其存储在数据库或消息传递基础架构(例如 JMS)中。消息侦听器将在任务到达时对其进行处理,并针对每个任务更新状态。

    权衡

    1. 可以在分布式模式下处理电子邮件请求。
    2. 可以重试电子邮件,不会产生任何副作用。
    3. 实现复杂,因为多个组件参与处理、持久化电子邮件请求。

    【讨论】:

    • 所以我认为最好的方法是将异步处理与多线程方法结合起来。每封需要发送的电子邮件都必须推送到数据库表 1。成功发送电子邮件后,可以将记录推送到另一个表,例如 table2。所有这些都可以单独发生在一个线程中..
    • 您不必维护单独的表。只需在同一张表中有一个状态字段,其中包含可能的值,如 PENDING、FAILED、SENT 等。
    猜你喜欢
    • 2012-05-07
    • 1970-01-01
    • 2015-08-04
    • 1970-01-01
    • 2010-09-08
    • 2011-06-09
    • 1970-01-01
    • 2013-02-12
    相关资源
    最近更新 更多