Search in sources :

Example 6 with RateLimiter

use of com.google.common.util.concurrent.RateLimiter in project cassandra by apache.

the class RateBasedBackPressure method apply.

@Override
public void apply(Set<RateBasedBackPressureState> states, long timeout, TimeUnit unit) {
    // Go through the back-pressure states, try updating each of them and collect min/max rates:
    boolean isUpdated = false;
    double minRateLimit = Double.POSITIVE_INFINITY;
    double maxRateLimit = Double.NEGATIVE_INFINITY;
    double minIncomingRate = Double.POSITIVE_INFINITY;
    RateLimiter currentMin = null;
    RateLimiter currentMax = null;
    for (RateBasedBackPressureState backPressure : states) {
        // Get the incoming/outgoing rates:
        double incomingRate = backPressure.incomingRate.get(TimeUnit.SECONDS);
        double outgoingRate = backPressure.outgoingRate.get(TimeUnit.SECONDS);
        // Compute the min incoming rate:
        if (incomingRate < minIncomingRate)
            minIncomingRate = incomingRate;
        // Try acquiring the interval lock:
        if (backPressure.tryIntervalLock(windowSize)) {
            // If acquired, proceed updating thi back-pressure state rate limit:
            isUpdated = true;
            try {
                RateLimiter limiter = backPressure.rateLimiter;
                // RateBasedBackPressureState):
                if (outgoingRate > 0) {
                    // Compute the incoming/outgoing ratio:
                    double actualRatio = incomingRate / outgoingRate;
                    // If the ratio is above the high mark, try growing by the back-pressure factor:
                    if (actualRatio >= highRatio) {
                        // Only if the outgoing rate is able to keep up with the rate increase:
                        if (limiter.getRate() <= outgoingRate) {
                            double newRate = limiter.getRate() + ((limiter.getRate() * factor) / 100);
                            if (newRate > 0 && newRate != Double.POSITIVE_INFINITY) {
                                limiter.setRate(newRate);
                            }
                        }
                    } else // If below, set the rate limiter at the incoming rate, decreased by factor:
                    {
                        // Only if the new rate is actually less than the actual rate:
                        double newRate = incomingRate - ((incomingRate * factor) / 100);
                        if (newRate > 0 && newRate < limiter.getRate()) {
                            limiter.setRate(newRate);
                        }
                    }
                    logger.trace("Back-pressure state for {}: incoming rate {}, outgoing rate {}, ratio {}, rate limiting {}", backPressure.getHost(), incomingRate, outgoingRate, actualRatio, limiter.getRate());
                } else // Otherwise reset the rate limiter:
                {
                    limiter.setRate(Double.POSITIVE_INFINITY);
                }
                // Housekeeping: pruning windows and resetting the last check timestamp!
                backPressure.incomingRate.prune();
                backPressure.outgoingRate.prune();
            } finally {
                backPressure.releaseIntervalLock();
            }
        }
        if (backPressure.rateLimiter.getRate() <= minRateLimit) {
            minRateLimit = backPressure.rateLimiter.getRate();
            currentMin = backPressure.rateLimiter;
        }
        if (backPressure.rateLimiter.getRate() >= maxRateLimit) {
            maxRateLimit = backPressure.rateLimiter.getRate();
            currentMax = backPressure.rateLimiter;
        }
    }
    // Now find the rate limiter corresponding to the replica group represented by these back-pressure states:
    if (!states.isEmpty()) {
        // Get the rate limiter:
        IntervalRateLimiter rateLimiter = rateLimiters.get(states, key -> new IntervalRateLimiter(timeSource));
        // If the back-pressure was updated and we acquire the interval lock for the rate limiter of this group:
        if (isUpdated && rateLimiter.tryIntervalLock(windowSize)) {
            try {
                // Update the rate limiter value based on the configured flow:
                if (flow.equals(Flow.FAST))
                    rateLimiter.limiter = currentMax;
                else
                    rateLimiter.limiter = currentMin;
                tenSecsNoSpamLogger.info("{} currently applied for remote replicas: {}", rateLimiter.limiter, states);
            } finally {
                rateLimiter.releaseIntervalLock();
            }
        }
        // Assigning a single rate limiter per replica group once per window size allows the back-pressure rate
        // limiting to be stable within the group itself.
        // Finally apply the rate limit with a max pause time equal to the provided timeout minus the
        // response time computed from the incoming rate, to reduce the number of client timeouts by taking into
        // account how long it could take to process responses after back-pressure:
        long responseTimeInNanos = (long) (TimeUnit.NANOSECONDS.convert(1, TimeUnit.SECONDS) / minIncomingRate);
        doRateLimit(rateLimiter.limiter, Math.max(0, TimeUnit.NANOSECONDS.convert(timeout, unit) - responseTimeInNanos));
    }
}
Also used : RateLimiter(com.google.common.util.concurrent.RateLimiter)

Example 7 with RateLimiter

use of com.google.common.util.concurrent.RateLimiter in project opennms by OpenNMS.

the class HeartbeatGenerator method start.

/**
 * Start.
 */
public synchronized void start() {
    stopped.set(false);
    final RateLimiter rateLimiter = RateLimiter.create(rate);
    thread = new Thread(new Runnable() {

        @Override
        public void run() {
            while (!stopped.get()) {
                rateLimiter.acquire();
                try (Context ctx = sendTimer.time()) {
                    dispatcher.send(new Heartbeat());
                    sentMeter.mark();
                }
            }
        }
    });
    thread.start();
}
Also used : Context(com.codahale.metrics.Timer.Context) RateLimiter(com.google.common.util.concurrent.RateLimiter)

Example 8 with RateLimiter

use of com.google.common.util.concurrent.RateLimiter in project tesla by linking12.

the class RateLimitHttpRequestFilter method doFilter.

@Override
public HttpResponse doFilter(HttpRequest originalRequest, HttpObject httpObject, ChannelHandlerContext channelHandlerContext) {
    if (httpObject instanceof HttpRequest) {
        HttpRequest httpRequest = (HttpRequest) httpObject;
        String url = httpRequest.uri();
        int index = url.indexOf("?");
        if (index > -1) {
            url = url.substring(0, index);
        }
        RateLimiter rateLimiter = null;
        try {
            rateLimiter = loadingCache.get(url);
        } catch (Throwable e) {
        }
        // 如果1秒钟没有获取令牌,说明被限制了
        if (rateLimiter != null && !rateLimiter.tryAcquire(1000, TimeUnit.MILLISECONDS)) {
            super.writeFilterLog(Double.toString(rateLimiter.getRate()), this.getClass(), "RateLimiter");
            return super.createResponse(HttpResponseStatus.TOO_MANY_REQUESTS, originalRequest);
        }
    }
    return null;
}
Also used : HttpRequest(io.netty.handler.codec.http.HttpRequest) RateLimiter(com.google.common.util.concurrent.RateLimiter)

Example 9 with RateLimiter

use of com.google.common.util.concurrent.RateLimiter in project free-framework by a601942905git.

the class LimiterTest1 method main.

public static void main(String[] args) {
    RateLimiter rateLimiter = RateLimiter.create(5.0);
    System.out.println(rateLimiter.acquire(5));
    System.out.println(rateLimiter.acquire(2));
    System.out.println(rateLimiter.acquire(1));
}
Also used : RateLimiter(com.google.common.util.concurrent.RateLimiter)

Example 10 with RateLimiter

use of com.google.common.util.concurrent.RateLimiter in project free-framework by a601942905git.

the class RateLimiterTest method testWithRateLimiter.

public static void testWithRateLimiter() {
    RateLimiter rateLimiter = RateLimiter.create(10);
    Long start = Clock.systemDefaultZone().millis();
    for (int i = 0; i < 20; i++) {
        System.out.println(rateLimiter.acquire());
    }
    Long end = Clock.systemDefaultZone().millis();
    System.out.println(end - start);
}
Also used : RateLimiter(com.google.common.util.concurrent.RateLimiter)

Aggregations

RateLimiter (com.google.common.util.concurrent.RateLimiter)64 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)20 BigInteger (java.math.BigInteger)16 ThreadPoolTaskExecutor (org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor)14 ParameterException (com.beust.jcommander.ParameterException)12 Test (org.junit.Test)12 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)10 ApplicationContext (org.springframework.context.ApplicationContext)10 ClassPathXmlApplicationContext (org.springframework.context.support.ClassPathXmlApplicationContext)10 Random (java.util.Random)9 ScheduledExecutorService (java.util.concurrent.ScheduledExecutorService)9 Service (org.fisco.bcos.channel.client.Service)9 Web3j (org.fisco.bcos.web3j.protocol.Web3j)9 ChannelEthereumService (org.fisco.bcos.web3j.protocol.channel.ChannelEthereumService)9 TransactionReceipt (org.fisco.bcos.web3j.protocol.core.methods.response.TransactionReceipt)9 Credentials (org.fisco.bcos.web3j.crypto.Credentials)8 ArrayList (java.util.ArrayList)7 ExecutorService (java.util.concurrent.ExecutorService)7 JCommander (com.beust.jcommander.JCommander)6 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)6