I am looking for a good solution or probably an API to solve the following problem:
- My application does a task in a loop, for example it sends e-mails etc. I need to limit the average rate of messages to for example 100 messages per second or 1000 messages per last minute ...
N开发者_JS百科o I am looking for an algorithm or an API which does exactly this task.
You can use a ScheduledExecutorService to schedule tasks for a given period of time.
For example, to schedule 100 tasks per second you can say:
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(nThreads);
scheduler.scheduleAtFixedRate(mailSender, 0, 10, TimeUnit.MILLISECONDS);
Obviously, you need to track how many tasks have executed and turn off the scheduler after the job is done.
Token bucket algorithm is very easy to implement and use yet very powerful. You can control the throughput at runtime and queue some requests to handle peeks.
The simplest way I can think of is to delay when to send each emails depending on how many are waiting.
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);
}
This will ensure that the tasks are performed only as close to together as the rate allows.
Guava has a RateLimiter class that does exactly that.
精彩评论