1: background

In high-concurrency service scenarios, three axes are commonly used: circuit breaker, downgrade, and current limiting. Next, we will focus on several implementation methods of common traffic limiting algorithms. Relevant test code to see: https://gitee.com/javadev/data-x

Pass the relevant test ab-N20 -c 15  http://localhost:8805/limiting/tpt
Copy the code

2: common solutions

1: Leaky bucket algorithm

Bucket algorithm idea is simple: we compared the water to be at the request of bucket to a system capacity limits, first into the water in the bucket, the water in the bucket in a certain flow rate, when the outflow rate is less than the rate of flow, due to the limited capacity of bucket, subsequent water directly into the overflow (rejected requests), to realize the current limit.

2: token bucket algorithm

The principle of the token bucket algorithm is more simple, the system will maintain a token (token) barrels, at a constant speed into a bucket into the token (token), if there are requests come in to be processed at this moment, you will need to first obtain a token from the pail (token), when there is no token bucket (token), then the request will be rejected. Token bucket algorithm can limit requests by controlling bucket capacity and token issuing rate.

<dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>30.1.1 - jre</version>
 </dependency>
 
static RateLimiter rateLimiter = RateLimiter.create(10);
if(! rateLimiter.tryAcquire()){String str = "Guavalimiting, I'm restricted, parameter =" +name +"," + LocalDateTime.now();
     logger.error(str);
}
Copy the code

3: Redis & Lua (Sliding Window Limiting)

Lua scripts are similar to stored procedures in MySQL databases in that they execute a set of commands, all of which either succeed or fail to achieve atomicity. You can also think of a Lua script as a block of code with business logic.

Local c c = redis.call('get',KEYS[1])

// If the call does not exceed the maximum value, return directly
if c and tonumber(c) > tonumber(ARGV[1]) then
return c;
end
// execute calculator autoadd
c = redis.call('incr',KEYS[1])
if tonumber(c) == 1 then

// Start limiting the stream from the first call and set the expiration of the corresponding key value
redis.call('expire',KEYS[1],ARGV[2])
end
return c;

KEYS[1] is used to represent parameter placeholders used as key values in Redis, mainly used to pass parameters used as keyz values in Redis. ARGV[1] is used as a placeholder for parameters in Redis. It is mainly used to pass parameters used as values in Redis.Copy the code

4: Sentinel current limiting (sliding window current limiting)

The Sentinel Control Desk combines the @SentinelResource annotation to achieve service flow limiting and fuse downgrading.

BlockHandler is only responsible for sentinel console configuration violations, and Fallback is only responsible for service exceptions. BolckException must be added to the parameter of the custom traffic limiting degrade method; otherwise, the defined method cannot be found

BlockHandlerClass Configures the traffic limiting degrade processing class, and configures the single Fallback fuse degrade processing method.

Sentinel If sentinel-Dashboard needs to be introduced, spring-cloud-starter-Alibaba -sentinel needs to be introducedCopy the code

3:

Traffic limiting is usually done at the Gateway layer, such as Nginx, Openresty, Kong, Zuul, Spring Cloud Gateway, etc., while the underlying implementation principle of Spring Cloud-Gateway traffic limiting is based on Redis + Lua. Through the built-in Lua flow limiting script.