我正在寻找一个好的解决方案或者可能是一个 API 来解决以下问题:
- 我的应用程序循环执行一项任务,例如它发送电子邮件等。我需要将平均消息速率限制为例如每秒 100 条消息或每最后一分钟 1000 条消息......
不,我正在寻找完全执行此任务的算法或 API。
我正在寻找一个好的解决方案或者可能是一个 API 来解决以下问题:
不,我正在寻找完全执行此任务的算法或 API。
您可以使用ScheduledExecutorService在给定的时间段内安排任务。
例如,要每秒安排 100 个任务,您可以说:
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(nThreads);
scheduler.scheduleAtFixedRate(mailSender, 0, 10, TimeUnit.MILLISECONDS);
显然,您需要跟踪执行了多少任务并在作业完成后关闭调度程序。
令牌桶算法非常易于实现和使用,但功能非常强大。您可以在运行时控制吞吐量并将一些请求排队以处理窥视。
我能想到的最简单的方法是延迟发送每封电子邮件的时间,具体取决于等待的数量。
final ScheduledThreadPoolExecutor service = new ScheduledThreadPoolExecutor(1);
int ratePerSecond = ...
public static void execute(Runnable run) {
int delay = 1000 * service.getQueue().size() / ratePerSecond;
service.schedule(run, delay, TimeUnit.MILLISECONDS);
}
这将确保任务仅在速率允许的情况下尽可能靠近地执行。
Guava 有一个RateLimiter类可以做到这一点。