侧边栏壁纸
  • 累计撰写 26 篇文章
  • 累计创建 35 个标签
  • 累计收到 9 条评论

目 录CONTENT

文章目录

Halo添加限流

Honesty
2020-07-19 / 0 评论 / 0 点赞 / 150 阅读 / 2,668 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-03-18,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

自部署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());
    }
0

评论区