自部署Halo后看了下代码实现,我估计我这小服务器怕是顶不住。所以想着加个限流处理。主要是加在页面和/api/content 上(怎么也不能把admin给限了啊),因还没有部署网关,暂时就加在Halo代码中
页面限流
看了下源码页面限流最终加在 ContentFilter 内容过滤器上
public ContentFilter(HaloProperties haloProperties,
OptionService optionService,
AbstractStringCacheStore cacheStore,
OneTimeTokenService oneTimeTokenService,
Limiter<Void> limiter) {
super(haloProperties, optionService, cacheStore, oneTimeTokenService);
addUrlPatterns("/**");
String adminPattern = HaloUtils.ensureBoth(haloProperties.getAdminPath(), "/") + "**";
addExcludeUrlPatterns(
adminPattern,
"/api/**",
"/install",
"/version",
"/js/**",
"/css/**");
// set failure handler
setFailureHandler(new ContentAuthenticationFailureHandler());
// 限流接口
this.limiter = limiter;
}
API限流
同上看源码再加ApiAuthenticationFilter上
Limiter限流器
关于Limiter限流器是一个自定义的限流工具
* 堵塞请求限流
* 该方法会被阻塞直到获取到请求
* @param callback 回调
* @return
*/
T acquire(LimiterCallback<T> callback) throws LimiterException;
/**
* 请求限流
* 获取指定许可数如果该许可数可以在不超过timeout的时间内获取得到的话,或者如果无法在timeout 过期之前获取得到许可数的话,那么立即返回
* @param timeout 超时时间
* @param unit 超时单位
* @param callback 回调
* @return
*/
T acquire(long timeout, TimeUnit unit,LimiterCallback<T> callback) throws LimiterException;
实现有4个
GuavaRateLimiter
基于google的令牌桶限流
* 使用 SmoothBursty 平滑突发性限流
* @see SmoothRateLimiter.SmoothBursty
* @param permitsPerSecond 每秒增加多少令牌-QPS
* @param permits 每次消耗多少个许可
*/
public GuavaRateLimiter(double permitsPerSecond, int permits){
this.limiter = RateLimiter.create( permitsPerSecond);
this.permits = permits;
}
/**
* 使用 SmoothWarmingUp 平滑预热限流
* SleepingStopWatch是一个可sleep的秒表,起始时间是构建StopWatch的时间,sleepMicrosUninterruptibly方法支持不受中断的sleep,sleep是当前线程的sleep。
* @see SmoothRateLimiter.SmoothWarmingUp
* @param permitsPerSecond 每秒增加多少令牌-QPS
* @param warmupPeriod 预热期时间
* @param unit 预热期时间单位
* @param permits 每次消耗多少许可
*/
public GuavaRateLimiter(double permitsPerSecond, long warmupPeriod, TimeUnit unit,int permits){
this.limiter = RateLimiter.create(permitsPerSecond,warmupPeriod ,unit );
this.permits = permits;
}
LeakyBucketLimiter
漏桶算法限流
/**
* 漏水的桶限幅器
*
* @param capacity 能力
* @param leakRate 泄漏率
* @param permits 许可证
*/
public LeakyBucketLimiter(int capacity,int leakRate, int permits) {
this.capacity = capacity;
this.leakRate = leakRate;
this.permits = permits;
this.leakTimeStamp = System.currentTimeMillis();
this.funnel = new Funnel(capacity,leakRate);
}
SemaphoreLimiter
计数器限流
/**
* 信号限幅器
* @param capacity 能力
* @param permits 许可证
* @param maxQueueLength
*/
public SemaphoreLimiter(int capacity, int permits, int maxQueueLength) {
this.semaphore = new Semaphore(capacity,true);
this.permits = permits;
this.maxQueueLength = maxQueueLength;
}
SlidingWindowsLimiter
滑动窗口限流
public SlidingWindowsLimiter(long window, int maxWindow) {
this.window = window;
this.maxWindow = maxWindow;
this.count = new AtomicInteger(0);
timeQueue.addFirst(System.currentTimeMillis());
}
评论区