//@VisibleForTesting public static RateLimiter create(double permitsPerSecond, SleepingStopwatch stopwatch) { RateLimiter rateLimiter = new SmoothBursty(stopwatch, 1.0 /* maxBurstSeconds */); rateLimiter.setRate(permitsPerSecond); return(rateLimiter); }
protected RateLimiter(SleepingStopwatch stopwatch) { if (stopwatch == null) { throw new ArgumentNullException("stopwatch 参数为空"); } this.stopwatch = stopwatch; }
/** * Creates a {@code RateLimiter} with the specified stable throughput, given as "permits per * second" (commonly referred to as <i>QPS</i>, queries per second). * * <p>The returned {@code RateLimiter} ensures that on average no more than {@code * permitsPerSecond} are issued during any given second, with sustained requests being smoothly * spread over each second. When the incoming request rate exceeds {@code permitsPerSecond} the * rate limiter will release one permit every {@code (1.0 / permitsPerSecond)} seconds. When the * rate limiter is unused, bursts of up to {@code permitsPerSecond} permits will be allowed, with * subsequent requests being smoothly limited at the stable rate of {@code permitsPerSecond}. * * @param permitsPerSecond the rate of the returned {@code RateLimiter}, measured in how many * permits become available per second * @throws IllegalArgumentException if {@code permitsPerSecond} is negative or zero */ // TODO(user): "This is equivalent to // {@code createWithCapacity(permitsPerSecond, 1, TimeUnit.SECONDS)}". public static RateLimiter create(double permitsPerSecond) { /* * The default RateLimiter configuration can save the unused permits of up to one second. This * is to avoid unnecessary stalls in situations like this: A RateLimiter of 1qps, and 4 threads, * all calling acquire() at these moments: * * T0 at 0 seconds * T1 at 1.05 seconds * T2 at 2 seconds * T3 at 3 seconds * * Due to the slight delay of T1, T2 would have to sleep till 2.05 seconds, and T3 would also * have to sleep till 3.05 seconds. */ return(create(permitsPerSecond, SleepingStopwatch.createFromSystemTimer())); }
public SmoothBursty(SleepingStopwatch stopwatch, double maxBurstSeconds) : base(stopwatch) { this.maxBurstSeconds = maxBurstSeconds; }
/** * @param warmupPeriod 表示在从冷启动速率过渡到平均速率的时间间隔 */ public SmoothWarmingUp( SleepingStopwatch stopwatch, long warmupPeriod, TimeUnit timeUnit, double coldFactor) : base(stopwatch) { this.warmupPeriodMicros = timeUnit.toMicros(warmupPeriod); this.coldFactor = coldFactor; }
//@VisibleForTesting public static RateLimiter create(double permitsPerSecond, long warmupPeriod, TimeUnit unit, double coldFactor, SleepingStopwatch stopwatch) { RateLimiter rateLimiter = new SmoothWarmingUp(stopwatch, warmupPeriod, unit, coldFactor); rateLimiter.setRate(permitsPerSecond); return(rateLimiter); }
/** * Creates a {@code RateLimiter} with the specified stable throughput, given as "permits per * second" (commonly referred to as <i>QPS</i>, queries per second), and a <i>warmup period</i>, * during which the {@code RateLimiter} smoothly ramps up its rate, until it reaches its maximum * rate at the end of the period (as long as there are enough requests to saturate it). Similarly, * if the {@code RateLimiter} is left <i>unused</i> for a duration of {@code warmupPeriod}, it * will gradually return to its "cold" state, i.e. it will go through the same warming up process * as when it was first created. * * <p>The returned {@code RateLimiter} is intended for cases where the resource that actually * fulfills the requests (e.g., a remote server) needs "warmup" time, rather than being * immediately accessed at the stable (maximum) rate. * * <p>The returned {@code RateLimiter} starts in a "cold" state (i.e. the warmup period will * follow), and if it is left unused for long enough, it will return to that state. * * @param permitsPerSecond the rate of the returned {@code RateLimiter}, measured in how many * permits become available per second * @param warmupPeriod the duration of the period where the {@code RateLimiter} ramps up its rate, * before reaching its stable (maximum) rate * @param unit the time unit of the warmupPeriod argument * @throws IllegalArgumentException if {@code permitsPerSecond} is negative or zero or {@code * warmupPeriod} is negative */ public static RateLimiter create(double permitsPerSecond, long warmupPeriod, TimeUnit unit) { //checkArgument(warmupPeriod >= 0, "warmupPeriod must not be negative: %s", warmupPeriod); return(create( permitsPerSecond, warmupPeriod, unit, 3.0, SleepingStopwatch.createFromSystemTimer())); }
private long nextFreeTicketMicros = 0L; // could be either in the past or future protected SmoothRateLimiter(SleepingStopwatch stopwatch) : base(stopwatch) { }