版权声明:本文为博主原创文章,未经博主允许不得转载。 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 这篇文章,使用过滤器进行过滤