2.算法-手写滑动窗口限流

限流

为啥要限流,大多数情况是服务器资源不足,短时间内大量流量请求到服务器,限流会有部分流量正常返回,部分流量异常,好过服务器宕机,所有流量异常返回的情况。

在代码世界上,限流有两种比较常见的算法:

1.令牌桶算法
2.漏桶算法

还有一种是滑动窗口限流,最早接触滑动窗口是TCP协议

滑动窗口

在这里插入图片描述

手写滑动窗口限流

设计思路:

Dqueue记录每次请求时间戳,每次计算时间窗口是否超过设定值,没有超出计数,超出清空Dqueue,计数归零,重新计算窗口。

简单的设计,单元测试可用,欢迎高手交流,此算法不推荐生产环境使用。
建议使用guvav 中限流算法

手写滑动窗口限流

public class slidingWindows {
    
    /**
     * 时间窗口
     **/
    private Long window;
    /**
     * 窗口的size 用于计算总的流量上限
     **/
    private Integer size = 2000;

    /**
     * 原子计数
     **/
    private AtomicInteger count;

    /**
     * Deque双队列
     */
    private Deque<Long> timequeue;


    public slidingWindows(Long windowCount) {
        this.window = windowCount;
        this.timequeue = new ConcurrentLinkedDeque<>();
        this.count = new AtomicInteger(0);
        timequeue.addFirst(System.currentTimeMillis());
    }

    /**
     * 流量限制
     **/
    public Boolean tryout() {
        Long now = System.currentTimeMillis();
        if ((now - timequeue.peekLast()) > window) {
            timequeue.clear();
            timequeue.addFirst(now);
            count.set(0);
        } else {
            if (count.addAndGet(1) < size) {
                timequeue.add(now);
                System.out.println("time: " + count.get());
                return true;
            }

        }
        return Boolean.FALSE;
    }

    public static void main(String[] args) {
        slidingWindows ms = new slidingWindows(1000L);

        // 创建固定大小的线程池
        ExecutorService threadPool = Executors.newFixedThreadPool(100);    // 创建线程池内最大num个线程同时执行

        // 创建线程
        // 开始全部将线程加入线程池
        // 执行num个线程同时执行
        for (int i = 0; i < 100000; i++) {
            Runnable r = new Runnable() {
                public void run() {
                    try {
                        sleep(10);
                        System.out.println(ms.tryout());
                        Thread t = Thread.currentThread();
                        /*System.out.println(t.getName());
                        System.out.println(t.getName());*/
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };
            threadPool.execute(r);
        }

        threadPool.shutdown();

    }
}

应用实践

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章