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(); } }
漏桶算法與令牌桶算法區別
主要區別在於“漏桶算法”能夠強行限制數據的傳輸速率,
而“令牌桶算法”在能夠限制數據的平均傳輸速率外,還允許某種程度的突發傳輸。在“令牌桶算法”中,只要令牌桶中存在令牌,那么就允許突發地傳輸數據直到達到用戶配置的門限,因此它適合於具有突發特性的流量