高並發解決方案限流技術-----漏桶算法限流


1,漏桶算法
漏桶作為計量工具(The Leaky Bucket Algorithm as a Meter)時,可以用於流量整形(Traffic Shaping)和流量控制(TrafficPolicing),漏桶算法的描述如下:
一個固定容量的漏桶,按照常量固定速率流出水滴;
如果桶是空的,則不需流出水滴;
可以以任意速率流入水滴到漏桶;
如果流入水滴超出了桶的容量,則流入的水滴溢出了(被丟棄),而漏桶容量是不變的。

2,

,

3,桶的容量代表最大並發量,如果桶滿了,則請求被丟棄

      固定速率流出

      隨意速率流入,流入代表請求,如果流入速率很快,將桶裝滿,則溢出的請求被放棄,以達到限流的效果。

4,java 代碼 漏桶類

package com.aiyuesheng.utils;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import lombok.Getter;
import lombok.Setter;

/**
 * 
 * @author caich5 可以把水滴看成請求
 */
@Setter
@Getter
public class LeakyBucket {
    // 桶的容量
    private int capacity = 100;
    // 木桶剩余的水滴的量(初始化的時候的空的桶)
    private AtomicInteger water = new AtomicInteger(0);
    // 水滴的流出的速率 每1000毫秒流出1滴
    private int leakRate;
    // 第一次請求之后,木桶在這個時間點開始漏水
    private long leakTimeStamp;

    public LeakyBucket(int leakRate) {
        this.leakRate = leakRate;
    }

    public boolean acquire() {
        // 如果是空桶,就當前時間作為桶開是漏出的時間
        if (water.get() == 0) {
            leakTimeStamp = System.currentTimeMillis();
            water.addAndGet(1);
            return capacity == 0 ? false : true;
        }
        // 先執行漏水,計算剩余水量
        int waterLeft = water.get() - ((int) ((System.currentTimeMillis() - leakTimeStamp) / 1000)) * leakRate;
        water.set(Math.max(0, waterLeft));
        // 重新更新leakTimeStamp
        leakTimeStamp = System.currentTimeMillis();
        // 嘗試加水,並且水還未滿
        if ((water.get()) < capacity) {
            water.addAndGet(1);
            return true;
        } else {
            // 水滿,拒絕加水
            return false;
        }
    }
}

實現:

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.LeakyBucket;
import com.aiyuesheng.utils.LimitService;
import com.alibaba.fastjson.JSONObject;
import com.google.common.util.concurrent.RateLimiter;

@RestController
public class Index {
//漏桶:水滴的漏出速率是每秒 1 滴
    private LeakyBucket leakyBucket = new LeakyBucket(1);

    @Autowired
    private OrderService orderService;
//漏桶限流
    @RequestMapping("/searchCustomerInfoByLeakyBucket")
    public Object searchCustomerInfoByLeakyBucket() {
        // 1.限流判斷
        boolean acquire = leakyBucket.acquire();
        if (!acquire) {
            System.out.println("稍后再試!");
            return "稍后再試!";
        }
        // 2.如果沒有達到限流的要求,直接調用接口查詢
        System.out.println(orderService.searchCustomerInfo());
        return orderService.searchCustomerInfo();
    }
    

}

漏桶算法與令牌桶算法區別

主要區別在於“漏桶算法”能夠強行限制數據的傳輸速率,

而“令牌桶算法”在能夠限制數據的平均傳輸速率外,還允許某種程度的突發傳輸。在“令牌桶算法”中,只要令牌桶中存在令牌,那么就允許突發地傳輸數據直到達到用戶配置的門限,因此它適合於具有突發特性的流量

 


免責聲明!

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



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