问题
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 ...
No I am looking for an algorithm or an API which does exactly this task.
回答1:
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.
回答2:
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.
回答3:
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.
回答4:
Guava has a RateLimiter class that does exactly that.
来源:https://stackoverflow.com/questions/7349941/rate-control-in-java