当前位置:网站首页>Three ways for redis to realize current limiting

Three ways for redis to realize current limiting

2022-07-01 19:12:00 Floating across the sea

Redis Three ways to realize current limiting

The first one is : be based on Redis Of setnx The operation of

We are using Redis When using distributed locks , We all know it depends on setnx Instructions , stay CAS(Compare and swap) During the operation of , At the same time, give the designated key Set up expired practices (expire), Our main purpose in limiting current is to , Yes and no N The number of requests that can access my code program . So rely on setnx You can easily do this function .
For example, we need to be in 10 Seconds limit 20 A request , So we're in setnx You can set the expiration time when 10, When requested setnx The number of 20 Then the current limiting effect is achieved . The code is relatively simple, so I won't show it .

Of course, there are many disadvantages of this approach , For example, when Statistics 1-10 seconds , Unable to statistics 2-11 In seconds , If you need statistics N Seconds M A request , So our Redis You need to keep N individual key Problems, etc.

The second kind : be based on Redis Data structure of zset

In fact, the most important part of current limiting is sliding window , As mentioned above 1-10 How to become 2-11. In fact, the starting value and the end value are respectively +1 that will do .

And if we use Redis Of list The data structure can easily realize this function

We can make the request into a zset Array , When every request comes in ,value Keep it unique , It can be used UUID Generate , and score Can be represented by the current timestamp , because score We can use it to calculate the number of requests within the current timestamp . and zset Data structures also provide range Methods make it easy for us to get 2 How many requests are in timestamps

The code is as follows

public Response limitFlow(){
    
        Long currentTime = new Date().getTime();
        System.out.println(currentTime);
        if(redisTemplate.hasKey("limit")) {
    
            Integer count = redisTemplate.opsForZSet().rangeByScore("limit", currentTime -  intervalTime, currentTime).size();        // intervalTime Is the time of current limiting  
            System.out.println(count);
            if (count != null && count > 5) {
    
                return Response.ok(" At most, you can only access 5 Time ");
            }
        }
        redisTemplate.opsForZSet().add("limit",UUID.randomUUID().toString(),currentTime);
        return Response.ok(" Successful visit ");
    }

The third kind of : be based on Redis The token bucket algorithm of

When it comes to current limiting, we have to mention the token bucket algorithm . For details, please refer to Du Niang's explanation [ Token bucket algorithm ][Link 1]
The token bucket algorithm refers to input rate and output rate , When the output rate is greater than the input rate , Then the flow limit is exceeded .
That is, every time we visit a request , It can be downloaded from Redis Get a token from , If you get the token , That means the limit is not exceeded , And if you can't get it , The result is the opposite .
Rely on the above ideas , We can combine Redis Of List Data structure can easily do such code , It's just a simple implementation
rely on List Of leftPop To get the token

//  Output token 
public Response limitFlow2(Long id){
    
        Object result = redisTemplate.opsForList().leftPop("limit_list");
        if(result == null){
    
            return Response.ok(" There is no token in the current token bucket ");
        }
        return Response.ok(articleDescription2);
    }

Rely on Java Scheduled tasks for , Go regularly List in rightPush token , Of course, tokens also need uniqueness , So I still use UUID Generated

// 10S Add... To token bucket at the rate of UUID, Just to guarantee uniqueness 
    @Scheduled(fixedDelay = 10_000,initialDelay = 0)
    public void setIntervalTimeTask(){
    
        redisTemplate.opsForList().rightPush("limit_list",UUID.randomUUID().toString());
    }
原网站

版权声明
本文为[Floating across the sea]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/182/202207011715176450.html