使用Guava的RateLimiter完成簡單的大流量限流


使用場景

系統使用下游資源時,需要考慮下游對資源受限、處理能力,在下游資源無法或者短時間內無法提升處理性能的情況下,可以使用限流器或者類似保護機制,避免下游服務崩潰造成整體服務的不可用。

常用算法

常見限流算法有兩種:漏桶算法和令牌桶算法

限流的一般思路:

1、隨機丟棄一定規則的用戶(迅速過濾掉90%的用戶);

2、MQ削峰(比如設一個MQ可以容納的最大消息量,達到這個量后MQ給予reject);

3、業務邏輯層使用RateLimiter(令牌桶算法)進行限流;

4、最終可以承受的流量到達DB層。

package ratelimiter;

import com.google.common.util.concurrent.RateLimiter;
import org.springframework.stereotype.Component;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @author xfyou
 * @date 2018/10/31
 */
@Component
public class AccessLimitService {

    private static volatile int acquireCount = 0;
    private static final Object OBJECT = new Object();

    /**
     * 每秒可以獲得50個許可證
     */
    private RateLimiter rateLimiter = RateLimiter.create(50);

    private boolean tryAcquire() {
        // 等待1秒鍾如果未能獲取到許可證就返回false,否則返回true
        return rateLimiter.tryAcquire(1, 1000, TimeUnit.MILLISECONDS);
    }

    public static void main(String[] args) {
        AccessLimitService accessLimitService = new AccessLimitService();
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < 1000; i++) {
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    if (accessLimitService.tryAcquire()) {
                        System.out.println("獲取許可證,執行業務邏輯。");
                        synchronized (OBJECT) {
                            System.out.println(++acquireCount);
                        }
                        try {
                            Thread.sleep(20);
                        } catch (InterruptedException ex) {
                            //
                        }
                    } else {
                        System.err.println("未獲取到許可證,請求可以丟棄。");
                    }
                }
            });
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        executorService.shutdown();
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM