RateLimiter high concurrent access limit

Use RateLimiter to complete simple large-traffic current limiting, snap-to-kill current limiting.
RateLimiter is an implementation class based on the token bucket algorithm provided by guava, which can easily complete the current limiting stunt and adjust the rate of token generation according to the actual situation of the system.
It can usually be applied to rush-purchase and current limiting to prevent the system from being overwhelmed; limit the amount of access to a certain interface and service per unit time, for example, some third-party services will limit the amount of user access; limit the network speed, how many bytes are only allowed to upload and download per unit time Wait.
Let's take a look at some simple practice demos. You need to introduce guava's maven dependencies first.
Demo1. There are many tasks, but hopefully no more than N per second

        import com.google.common.util.concurrent.RateLimiter;  
    import java.util.ArrayList;  
    import java.util.List;  
    import java.util.concurrent.ExecutorService;  
    import java.util.concurrent.Executors;  

    /** 
     *  
     * 有很多个任务,但希望每秒不超过X个,可用此类 
     */  
    public class Demo1 {  
        public static void main(String[] args) {  
            //0.5代表一秒最多多少个  
            RateLimiter rateLimiter = RateLimiter.create(0.5);  
            List<Runnable> tasks = new ArrayList<Runnable>();  
            for (int i = 0; i < 10; i++) {  
                tasks.add(new UserRequest(i));  
            }  
            ExecutorService threadPool = Executors.newCachedThreadPool();  
            for (Runnable runnable : tasks) {  
                System.out.println("等待时间:" + rateLimiter.acquire());  
                threadPool.execute(runnable);  
            }  
        }  

        private static class UserRequest implements Runnable {  
            private int id;  

            public UserRequest(int id) {  
                this.id = id;  
            }  

            public void run() {  
                System.out.println(id);  
            }  
    }  

}

Demo2. Current limit in panic buying scenario
If we estimate that the database can withstand concurrency of 10, if it exceeds 10, it may cause a failure, we can limit the current of the request interface.

        import com.google.common.util.concurrent.RateLimiter;  
    import com.tianyalei.model.GoodInfo;  
    import com.tianyalei.service.GoodInfoService;  
    import org.springframework.web.bind.annotation.RequestMapping;  
    import org.springframework.web.bind.annotation.RestController;  
    import javax.annotation.Resource;  

    @RestController  
    public class IndexController {  
        @Resource(name = "db")  
        private GoodInfoService goodInfoService;  

        RateLimiter rateLimiter = RateLimiter.create(10);  

        @RequestMapping("/miaosha")  
        public Object miaosha(int count, String code) {  
            System.out.println("等待时间" + rateLimiter.acquire());  
            if (goodInfoService.update(code, count) > 0) {  
                return "购买成功";  
            }  
            return "购买失败";  
        }  
        @RequestMapping("/add")  
        public Object add() {  
            for (int i = 0; i < 100; i++) {  
                GoodInfo goodInfo = new GoodInfo();  
                goodInfo.setCode("iphone" + i);  
                goodInfo.setAmount(100);  
                goodInfoService.add(goodInfo);  
            }  
            return "添加成功";  
        }  
    }  

Demo3. Downgrade of panic buying scene

     /** 
     * tryAcquire(long timeout, TimeUnit unit) 
     * 从RateLimiter 获取许可如果该许可可以在不超过timeout的时间内获取得到的话, 
     * 或者如果无法在timeout 过期之前获取得到许可的话,那么立即返回false(无需等待) 
     */  
    @RequestMapping("/buy")  
    public Object miao(int count, String code) {  
        //判断能否在1秒内得到令牌,如果不能则立即返回false,不会阻塞程序  
        if (!rateLimiter.tryAcquire(1000, TimeUnit.MILLISECONDS)) {  
            System.out.println("短期无法获取令牌,真不幸,排队也瞎排");  
            return "失败";  
        }  
        if (goodInfoService.update(code, count) > 0) {  
            System.out.println("购买成功");  
            return "成功";  
        }  
        System.out.println("数据不足,失败");  
        return "失败";  
    }  

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325721094&siteId=291194637