google的RateLimiter限流器的使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011955252/article/details/83992586

背景:A系统需要调用B,C,D系统,B,C,D系统没有能力做限流,因此需要A系统针对B,C,D系统做限流,每秒发送对象要求的请求数。可以使用下面的组件进行控制

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.util.concurrent.RateLimiter;

import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

/**
 * 公共限流器<p>
 *
 * 内部维持一个限流器集合<p>
 *
 * 同一个identify(身份),同一个限流上限值 公用一个限流器.<p>
 *
 * 如果某一个identify的限流值改了,则使用新的限流器.原有的限流器会因为缓存失效而被回收。<p>
 */
public class CommonRateLimiterManager {


    /**
     * 限流器缓存
     *
     * key:identify+permitsPerSnd
     *
     * value:限流器实例
     * */
    private static final Cache<String, RateLimiter> RATE_LIMITER_CACHE = CacheBuilder.newBuilder()
        .maximumSize(2000).expireAfterWrite(7, TimeUnit.DAYS).build();

    /**
     * 申请获取一个许可<p>
     *
     * 同一个 identify 共享一个限速器<p>
     *
     * @param identify 身份信息
     * @param permitsPerSnd 当前的限速值
     */
    public static void acquireOnePermit(final String identify, final double permitsPerSnd) {
        try {
            RateLimiter rateLimiter = RATE_LIMITER_CACHE.get(identify, new Callable<RateLimiter>() {

                /**
                 * Computes a result, or throws an exception if unable to do so.
                 *
                 * @return computed result
                 * @throws Exception if unable to compute a result
                 */
                @Override
                public RateLimiter call() throws Exception {
                    System.out.println("已创建限流组件-[identify={0}, permitsPerSnd={1}]."+identify+"--"+
                        permitsPerSnd);
                    return RateLimiter.create(permitsPerSnd);
                }
            });

            rateLimiter.acquire();
        } catch (Exception e) {
            System.out.println("获取限流组件时异常,identify={0},permitsPerSnd={1}."+ identify+"--"+permitsPerSnd);
        }
    }

    /**
     * 如果获取到就返回true.否则返回false.
     * 这个是不阻塞当前线程的
     * @param identify
     * @param permitsPerSnd
     */
    public static boolean tryAcquireOnePermit(final String identify, final double permitsPerSnd) {
        try {
            RateLimiter rateLimiter = RATE_LIMITER_CACHE.get(identify, new Callable<RateLimiter>() {

                /**
                 * Computes a result, or throws an exception if unable to do so.
                 *
                 * @return computed result
                 * @throws Exception if unable to compute a result
                 */
                @Override
                public RateLimiter call() throws Exception {
                    System.out.println("已创建限流组件-[identify={0}, permitsPerSnd={1}]."+identify+"--"+
                            permitsPerSnd);
                    return RateLimiter.create(permitsPerSnd);
                }
            });

            return rateLimiter.tryAcquire();
        } catch (Exception e) {
            System.out.println("获取限流组件时异常,identify={0},permitsPerSnd={1}."+ identify+"--"+
                    permitsPerSnd);
            return false;
        }
    }
}

 如果A系统是一个Web系统,A系统也需要限流,可以借鉴https://blog.csdn.net/cloud_ll/article/details/43602325  这篇文章,使用过滤器进行过滤

猜你喜欢

转载自blog.csdn.net/u011955252/article/details/83992586