高並發解決方案限流技術-----使用RateLimiter實現令牌桶限流


1,RateLimiter是guava提供的基於令牌桶算法的實現類,可以非常簡單的完成限流特技,並且根據系統的實際情況來調整生成token的速率。
通常可應用於搶購限流防止沖垮系統;限制某接口、服務單位時間內的訪問量,譬如一些第三方服務會對用戶訪問量進行限制;限制網速,單位時間內只允許上傳下載多少字節等。

guava的maven依賴

<dependency>
     <groupId>com.google.guava</groupId>
     <artifactId>guava</artifactId>
     <version>25.1-jre</version>
 </dependency>

2,令牌桶的原理,有一個獨立線程一直以一個固定的速率往桶中存放令牌

   客戶端去桶中獲取令牌,獲取到令牌,就可以訪問,獲取不到,說明請求過多,需要服務降級。

3,

package com.aiyuesheng.controller;

import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.aiyuesheng.hystrix.OrderHystrixCommand;
import com.aiyuesheng.service.OrderService;
import com.aiyuesheng.utils.LimitService;
import com.alibaba.fastjson.JSONObject;
import com.google.common.util.concurrent.RateLimiter;

@RestController
public class Index {// 令牌桶:1.0 表示 每秒中生成1個令牌存放在桶中
    RateLimiter rateLimiter = RateLimiter.create(1.0);

    @Autowired
    private OrderService orderService;
//令牌桶限流
    @RequestMapping("/searchCustomerInfoByRateLimiter")
    public Object searchCustomerInfoByRateLimiter() {
        // 1.限流判斷
        // 如果在0.5秒內 沒有獲取不到令牌的話,則會一直等待
        System.out.println("生成令牌等待時間:" + rateLimiter.acquire());
        boolean acquire = rateLimiter.tryAcquire(500, TimeUnit.MILLISECONDS); // 每次發送請求,願意等待0.5秒,如果設為1秒,每次都能查詢成功,因為沒秒中都會放入一個令牌到桶中
        if (!acquire) {
            System.out.println("稍后再試!");
            return "稍后再試!";
        }
        // 2.如果沒有達到限流的要求,直接調用接口查詢
        System.out.println(orderService.searchCustomerInfo());
        return orderService.searchCustomerInfo();
    }

}

 


免責聲明!

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



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