实现@Async
方法的最佳方法是每Y个毫秒/秒执行X个时间。
我有亚马逊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) {
//...
}
答案 0 :(得分:1)
@Async
注释仅表示方法的异步执行,它不提供任何速率限制或其他功能。
一种笨拙的方式是使用大小为1的池,并且方法本身有72
毫秒的延迟。更好的方法是忘记@Async
并使用对速率限制有意义的东西。
答案 1 :(得分:1)
开箱即用,想要更多地关注你的要求让我把它放在桌面上作为一个非常有效的选择,我在过去的类似情况下使用过,我有时间限制。
名为Throttler
的企业集成模式( EIP )可以完美地解决此速率限制问题。
Apache Camel Throttler implementation允许您指定:
maximumRequestsPerPeriod
= 您案件中每个节流的最大请求数 14 timePeriodMillis
= 时间段(以毫秒为单位),在此情况下,节流器最多允许maximumRequestsPerPeriod
条消息 1000 (这是默认的方式)这可以用XML或Java方式定义,它还提供Async非阻塞选项(如果电子邮件没有使这个迭代安排它们发生在下一个可用的插槽中)。
提供EIP的Spring解决方案Spring Integration也应该提供Throttler选项,但我自己并没有使用Spring Integration知道。
同样,我理解学习新内容的开销,这可能不会发生在你的案例中,但我想概述它以备将来参考,并为你的问题提供一个独立的解决方案。