google的RateLimiter限流器的使用
阿新 • • 發佈:2018-12-30
背景: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; } } }