1,漏桶算法
漏桶作为计量工具(The Leaky Bucket Algorithm as a Meter)时,可以用于流量整形(Traffic Shaping)和流量控制(TrafficPolicing),漏桶算法的描述如下:
一个固定容量的漏桶,按照常量固定速率流出水滴;
如果桶是空的,则不需流出水滴;
可以以任意速率流入水滴到漏桶;
如果流入水滴超出了桶的容量,则流入的水滴溢出了(被丢弃),而漏桶容量是不变的。
2,
,
3,桶的容量代表最大并发量,如果桶满了,则请求被丢弃
固定速率流出
随意速率流入,流入代表请求,如果流入速率很快,将桶装满,则溢出的请求被放弃,以达到限流的效果。
4,java 代码 漏桶类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 1package com.aiyuesheng.utils;
2
3import java.util.concurrent.TimeUnit;
4import java.util.concurrent.atomic.AtomicInteger;
5
6import lombok.Getter;
7import lombok.Setter;
8
9/**
10 *
11 * @author caich5 可以把水滴看成请求
12 */
13@Setter
14@Getter
15public class LeakyBucket {
16 // 桶的容量
17 private int capacity = 100;
18 // 木桶剩余的水滴的量(初始化的时候的空的桶)
19 private AtomicInteger water = new AtomicInteger(0);
20 // 水滴的流出的速率 每1000毫秒流出1滴
21 private int leakRate;
22 // 第一次请求之后,木桶在这个时间点开始漏水
23 private long leakTimeStamp;
24
25 public LeakyBucket(int leakRate) {
26 this.leakRate = leakRate;
27 }
28
29 public boolean acquire() {
30 // 如果是空桶,就当前时间作为桶开是漏出的时间
31 if (water.get() == 0) {
32 leakTimeStamp = System.currentTimeMillis();
33 water.addAndGet(1);
34 return capacity == 0 ? false : true;
35 }
36 // 先执行漏水,计算剩余水量
37 int waterLeft = water.get() - ((int) ((System.currentTimeMillis() - leakTimeStamp) / 1000)) * leakRate;
38 water.set(Math.max(0, waterLeft));
39 // 重新更新leakTimeStamp
40 leakTimeStamp = System.currentTimeMillis();
41 // 尝试加水,并且水还未满
42 if ((water.get()) < capacity) {
43 water.addAndGet(1);
44 return true;
45 } else {
46 // 水满,拒绝加水
47 return false;
48 }
49 }
50}
51
实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 1package com.aiyuesheng.controller;
2
3import java.util.concurrent.TimeUnit;
4
5import org.springframework.beans.factory.annotation.Autowired;
6import org.springframework.beans.factory.annotation.Value;
7import org.springframework.web.bind.annotation.RequestMapping;
8import org.springframework.web.bind.annotation.RestController;
9
10import com.aiyuesheng.hystrix.OrderHystrixCommand;
11import com.aiyuesheng.service.OrderService;
12import com.aiyuesheng.utils.LeakyBucket;
13import com.aiyuesheng.utils.LimitService;
14import com.alibaba.fastjson.JSONObject;
15import com.google.common.util.concurrent.RateLimiter;
16
17@RestController
18public class Index {
19//漏桶:水滴的漏出速率是每秒 1 滴
20 private LeakyBucket leakyBucket = new LeakyBucket(1);
21
22 @Autowired
23 private OrderService orderService;
24//漏桶限流
25 @RequestMapping("/searchCustomerInfoByLeakyBucket")
26 public Object searchCustomerInfoByLeakyBucket() {
27 // 1.限流判断
28 boolean acquire = leakyBucket.acquire();
29 if (!acquire) {
30 System.out.println("稍后再试!");
31 return "稍后再试!";
32 }
33 // 2.如果没有达到限流的要求,直接调用接口查询
34 System.out.println(orderService.searchCustomerInfo());
35 return orderService.searchCustomerInfo();
36 }
37
38
39}
40