0

@Async实现每 Y 毫秒/秒执行 X 次的方法的最佳方法是什么。

我要求 Amazon SES 每秒仅发送 14 封电子邮件,我正在使用 Spring 的 @Async 注释异步执行此操作,但据我所知,我只能设置最大池和最大队列大小,而不能设置速率。

这是我所拥有的:

@Bean(name = "emailSenderThreadPoolTaskExecutor")
public Executor emailSenderThreadPoolTaskExecutor() {

    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(14); // send 14 at once
    executor.setMaxPoolSize(14);
    executor.setThreadNamePrefix("EmailThreadPool-");
    executor.initialize();
    return executor;
}

接着

@Async(value = "emailSenderThreadPoolTaskExecutor")
public void sendEmail(String emailTo, String subject) {
    //...
}
4

2 回答 2

1

注释仅暗示方法的@Async异步执行,它不提供任何速率限制或其他功能。

一种笨拙的方法是使用大小为 1 的池,并72在方法本身中有毫秒的延迟。更好的方法是忘记@Async并使用一些用于速率限制的东西。

于 2016-11-30T21:14:23.993 回答
1

开箱即用地思考更多地关注您的要求,让我把它作为一个非常有效的选项放在桌面上,我在过去有时间计数器限制的类似情况下使用过。

所谓的企业集成模式(EIPThrottler可以完美解决这个限速问题。

Apache Camel Throttler 实现允许您指定:

  • maximumRequestsPerPeriod=在您的情况下,每个周期限制的最大请求数14
  • timePeriodMillis=以毫秒为单位的时间段,maximumRequestsPerPeriod在您的情况下,节流器最多允许消息数为1000(顺便说一下,这是默认值)

这可以用 XML 或 Java 方式定义,它还提供异步非阻塞选项(如果电子邮件没有使其成为此迭代,则安排它们发生在下一个可用插槽)。

Spring Integration,提供 EIP 的 Spring 解决方案,也应该有 Throttler 选项可用,但我自己没有使用 Spring Integration 知道。

同样,我理解学习新事物的开销,这可能不会在您的情况下发生,但无论如何我想概述它以供将来参考和您的问题的独立解决方案。

于 2016-11-30T21:35:24.857 回答