zoukankan      html  css  js  c++  java
  • 高并发解决方案限流技术-----漏桶算法限流

    1,漏桶算法
    漏桶作为计量工具(The Leaky Bucket Algorithm as a Meter)时,可以用于流量整形(Traffic Shaping)和流量控制(TrafficPolicing),漏桶算法的描述如下:
    一个固定容量的漏桶,按照常量固定速率流出水滴;
    如果桶是空的,则不需流出水滴;
    可以以任意速率流入水滴到漏桶;
    如果流入水滴超出了桶的容量,则流入的水滴溢出了(被丢弃),而漏桶容量是不变的。

    2,

    ,

    3,桶的容量代表最大并发量,如果桶满了,则请求被丢弃

          固定速率流出

          随意速率流入,流入代表请求,如果流入速率很快,将桶装满,则溢出的请求被放弃,以达到限流的效果。

    4,java 代码 漏桶类

    package com.aiyuesheng.utils;
    
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.atomic.AtomicInteger;
    
    import lombok.Getter;
    import lombok.Setter;
    
    /**
     * 
     * @author caich5 可以把水滴看成请求
     */
    @Setter
    @Getter
    public class LeakyBucket {
        // 桶的容量
        private int capacity = 100;
        // 木桶剩余的水滴的量(初始化的时候的空的桶)
        private AtomicInteger water = new AtomicInteger(0);
        // 水滴的流出的速率 每1000毫秒流出1滴
        private int leakRate;
        // 第一次请求之后,木桶在这个时间点开始漏水
        private long leakTimeStamp;
    
        public LeakyBucket(int leakRate) {
            this.leakRate = leakRate;
        }
    
        public boolean acquire() {
            // 如果是空桶,就当前时间作为桶开是漏出的时间
            if (water.get() == 0) {
                leakTimeStamp = System.currentTimeMillis();
                water.addAndGet(1);
                return capacity == 0 ? false : true;
            }
            // 先执行漏水,计算剩余水量
            int waterLeft = water.get() - ((int) ((System.currentTimeMillis() - leakTimeStamp) / 1000)) * leakRate;
            water.set(Math.max(0, waterLeft));
            // 重新更新leakTimeStamp
            leakTimeStamp = System.currentTimeMillis();
            // 尝试加水,并且水还未满
            if ((water.get()) < capacity) {
                water.addAndGet(1);
                return true;
            } else {
                // 水满,拒绝加水
                return false;
            }
        }
    }

    实现:

    package com.aiyuesheng.controller;
    
    import java.util.concurrent.TimeUnit;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.aiyuesheng.hystrix.OrderHystrixCommand;
    import com.aiyuesheng.service.OrderService;
    import com.aiyuesheng.utils.LeakyBucket;
    import com.aiyuesheng.utils.LimitService;
    import com.alibaba.fastjson.JSONObject;
    import com.google.common.util.concurrent.RateLimiter;
    
    @RestController
    public class Index {
    //漏桶:水滴的漏出速率是每秒 1 滴
        private LeakyBucket leakyBucket = new LeakyBucket(1);
    
        @Autowired
        private OrderService orderService;
    //漏桶限流
        @RequestMapping("/searchCustomerInfoByLeakyBucket")
        public Object searchCustomerInfoByLeakyBucket() {
            // 1.限流判断
            boolean acquire = leakyBucket.acquire();
            if (!acquire) {
                System.out.println("稍后再试!");
                return "稍后再试!";
            }
            // 2.如果没有达到限流的要求,直接调用接口查询
            System.out.println(orderService.searchCustomerInfo());
            return orderService.searchCustomerInfo();
        }
        
    
    }

    漏桶算法与令牌桶算法区别

    主要区别在于“漏桶算法”能够强行限制数据的传输速率,

    而“令牌桶算法”在能够限制数据的平均传输速率外,还允许某种程度的突发传输。在“令牌桶算法”中,只要令牌桶中存在令牌,那么就允许突发地传输数据直到达到用户配置的门限,因此它适合于具有突发特性的流量

  • 相关阅读:
    java编程思想 第三章
    linux安装beego框架环境
    Windows安装beego框架环境
    js 版本号比较实现
    vue element el-table 数据渲染报错 Invalid prop: type check failed for prop "data". Expected Array, got Object
    error c:/wamp64 or php in path
    第三章 函数
    第二章 有意义的命名
    curl实现多路并发请求(请求数量大时再次分割实现循环处理)
    js中常用方法集合
  • 原文地址:https://www.cnblogs.com/pickKnow/p/11253005.html
Copyright © 2011-2022 走看看