• 接口限流实现


    有一个API网关,出于对API接口的保护,需要建立一个流控功能,根据API名称,每分钟最多只能请求指定的次数(如1000次),超过限制则这分钟内返回错误,但下一分钟又可以正常请求。

    代码部分:

    工具类:

    public class API {
    
        /*
        超时时间
         */
        private long time;
    
        /*
        请求API的次数
         */
        private int count;
    
        public long getTime() {
            return time;
        }
    
        public void setTime(long time) {
            this.time = time;
        }
    
        public int getCount() {
            return count;
        }
    
        public void setCount(int count) {
            this.count = count;
        }
    
        public boolean isValid(){
            System.out.println(System.currentTimeMillis()/1000);
            // 没有超时
            if(System.currentTimeMillis()/1000 < time){
                if(this.count < 10){
                  // 请求小于10次则表示请求成功(为了测试方便没有设为题意的1000)
                    this.count ++;
                    System.out.println("执行成功");
                    return true;
                }else{
                    System.out.println("请求超出1000次,失败");
                    return false;
                }
            }else{
              // 触发限流则重置
                System.out.println("----------重置----------");
                this.count = 1;
                this.setTime(System.currentTimeMillis()/1000 + 1);
                return true;
            }
        }
    }

      

    入口:

    import javax.sound.midi.Soundbank;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    
    public class UseApi {
      /*
      *  用一个map来记录请求的名字和频次
      */
        private static Map<String, API> map = new HashMap<>();
    
        public boolean invoke(String name){
    
            if (name.isEmpty()){
                return false;
            }
    
            synchronized (map){
                System.out.println(map.containsKey(name));
                // 第一次请求该命令
                if(!map.containsKey(name)){
                    API api = new API();
                    api.setTime(System.currentTimeMillis()/1000 + 1);
                    api.setCount(1);
                    map.put(name, api);
                    return true;
                }else{
                    API api = map.get(name);
                    return api.isValid();
                }
            }
        }
      
      // 测试方法,线程里面请求10次同一个方法 method1
        public static Runnable getThread(){
            return new Runnable() {
                @Override
                public void run() {
                    for(int i = 0; i < 10; i ++){
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        UseApi useApi = new UseApi();
                        System.out.println(useApi.invoke("method1"));
                    }
                }
            };
        }
    
        public static void main(String[] args) {
    
            ExecutorService executorService = Executors.newFixedThreadPool(10);
        // 开10个线程进行测试
            for (int i = 0; i < 10; i++) {
                executorService.submit(getThread());
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
    
            executorService.shutdown();
    
        }
    
    
    }
  • 相关阅读:
    [转].net自定义验证控件CustomValidator的使用
    After Effects CS4入门经典—高手之路
    [转]用JS获取地址栏参数的方法(超级简单)
    SpringBoot中通过SpringBootServletInitializer如何实现容器初始化
    SpringBoot之二:部署Spring Boot应用程序方式
    Zookeeper学习(八):Zookeeper的数据发布与订阅模式
    Dubbo各种协议详解
    Annotation之四:注解中的-Xlint:unchecked和 -Xlint:deprecation
    mina在spring中的配置多个端口
    Mina2中IoService
  • 原文地址:https://www.cnblogs.com/Soy-technology/p/15098837.html
Copyright © 2020-2023  润新知