java - Spring 中的异步事件需要大量时间来执行(轮到它了)

标签 java spring spring-mvc asynchronous

我有一个应用程序,每当对端点进行 REST 调用时,我都需要触发电子邮件。设计是每当调用 REST 调用时,我将数据保存在数据库中,发出一个异步事件并返回。

我的问题是,由于大量请求不断涌现,发出的异步事件在很长一段时间内都没有机会。有时,随着服务器运行数周,延迟不断增加。

场景

  1. 调用服务器端点
  2. 服务器将数据保存到数据库,发出一个 Spring 异步事件
  3. 从端点返回

调用 2 会延迟,因为有时会很晚调用监听器。

public class DataController {   
    @Inject
    ApplicationEventPublisher eventPublisher;

    @RequestMapping(value = "data", method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void addData(@RequestBody DataDTO data) {
        dataService.addData(data);
        eventPublisher.publishEvent(new DataRequest(new DataDTO());
    }
}



public class DataRequest extends ApplicationEvent {


    private DataDTO dataDTO;

    public DataRequest(DataDTO dataDTO) {
        super(dataDTO);
        this.dataDTO = dataDTO;
    }
}

@Component
public class DataListener {

    @EventListener
    @Async
    private void dataListener(DataDTO dataDTO) {
        // Send email
    }
}

因为它是一个异步事件,JVM 给了 dataListener 很晚执行的机会。有时 较早触发的事件比之后触发的事件获得机会晚。

所以 2 个基本问题

  1. 电子邮件延迟。延迟范围从 1 分钟到 4 小时到 8 天等不等
  2. 如果一个事件在中午 12 点触发发送电子邮件至 xyz@gmail.com,另一个事件在中午 12:15 发送电子邮件至 abc@gmail.com,则 abc@gmail.com 有可能收到电子邮件在 xyz@gmail.com 之前。

感谢您的帮助

最佳答案

Spring 异步事件受限于线程池的大小,一旦传入请求高于 Activity 线程的大小,就会出现延迟。

您需要使用 RabbitMQ、Kafka 等消息队列。您的架构应该更改为执行以下操作;

  1. 在 REST 端点中使用电子邮件地址、数据库条目数据等所有信息序列化 JSON 消息,并将该 JSON 消息存储在消息队列中并返回状态代码
  2. 消息队列(独立的 Java 应用程序)必须有消费者,当消息队列中有数据时,他们会轮询或收到通知。
  3. 这些消费者应该反序列化 JSON 消息,在数据库中保存一个条目并发送电子邮件。

通过这种架构,您可以在高负载时增加消费者,从而根据需要进行扩展。

关于java - Spring 中的异步事件需要大量时间来执行(轮到它了),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45273708/

相关文章:

Spring Security logout-success-url 不被认可

java - Apache Camel : I can't get an object out of the body and transform it

java - 当我们点击 spring mvc 中的链接时,如何在新窗口中显示日志文件的内容

java - 动态调用 Spring Integration 变压器

java - PatternLayout (log4j) 的 C、F、L、l 和 M 到底有多慢?

java - 反序列化后如何将对象重新附加到 EclipseLink session

java - 如何在 javafx 中隐藏组合框上的向下箭头按钮?

c# - Spring.Net 中包含通用字典的通用字典

spring-mvc - Spring MVC : The request sent by the client was syntactically incorrect

java - 匹配日期模式的代码