Token bucket current limiting is implemented through semaphores

Scenes

1. In order to prevent uncontrolled calls from third parties from bringing down our system, we need to limit the flow of important requests.
2. The service provider has a per-minute flow limit for the interface we call.

Scenario 1 is usually supported by a relatively mature framework, and only requires simple configuration to introduce a current limiting mechanism into the system such as alibaba sentinel, spring cloud hystrix

Scenario 2: The service provider limits our flow. In order to obtain the service results correctly, we also need to limit the flow of our requests.

Several common current limiting schemes

Counting current limit, fixed window, sliding window, leaky bucket algorithm, token bucket

The simplest solution

It is not the above current limiting algorithm, since the other party limits us, then we only need to keep requesting, if the request result is a limited request, then we sleep for a period of time, and then continue to initiate requests

public class WeTask{
    
    

    public static void main(String[] args) {
    
    
        // 伪代码
        task(1);
    }

    public Static void  task(int para) {
    
    
        
        Boolean res = getResponse();
        if (!res) {
    
    
           //限流了
            Thread.sleep(1000);
            // 继续发起上次请求
            task(para);
        }
        // 处理结果
        dosomething()
    }
}

Token bucket is implemented through semaphore

Since we limit our own requests and the other party limits our results, we use token buckets to control our requests according to the limit of 300 requests per minute given by the other party.

A lot of details are omitted in the code, mainly to understand how the semaphore implements the token bucket, and the two methods of acquire and release are used to get and put into the bucket.

public class WeTask{
    
    
        
        @autowire
        Semaphore apiSemaphore;

         @Bean(name = "apiSemaphore")
         public Semaphore apiSemaphore() {
    
    
         Semaphore apiSemaphore = new Semaphore(40, true);
         scheduledThreadPoolExecutor.scheduleAtFixedRate(() -> {
    
    
            try {
    
    
                // 每10s往桶里放允许的请求数
                log.info("release ...40");
                apiSemaphore.release(40);
            } catch (Exception e) {
    
    
                log.error(e.getMessage(), e);
            }
         }, -1, 10, TimeUnit.SECONDS);
         return apiSemaphore;
     }


     public static void main(String[] args) {
    
    
        // 伪代码
        task(1);
    }

    public Static void  task(int para) {
    
    
        apiSemaphore.acquire();
        Boolean res = getResponse();
        //伪代码 还要再次判断可能限流(不信任原则,对方可能会调整限流量)
        // 处理结果
        dosomething()
    }

}

APIs involved

scheduledThreadPoolExecutor: The scheduled task thread pool is similar to Timer, but more powerful than it and supports multi-threaded scheduled tasks.

Semaphore: semaphore, internal class inheritance to implement AQS, supports fair and unfair locks

For other related knowledge points, please refer to the previous article: Fences and Locks

https://blog.csdn.net/u013565163/article/details/87310700

Guess you like

Origin blog.csdn.net/u013565163/article/details/129857374