高并发解决方案限流技术-----漏桶算法限流
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(); } }
漏桶算法与令牌桶算法区别
主要区别在于“漏桶算法”能够强行限制数据的传输速率,
而“令牌桶算法”在能够限制数据的平均传输速率外,还允许某种程度的突发传输。在“令牌桶算法”中,只要令牌桶中存在令牌,那么就允许突发地传输数据直到达到用户配置的门限,因此它适合于具有突发特性的流量
Aimer,c'est partager