简单方法限流实现-利用缓存通道写满时写阻塞, 为空时读阻塞的特性

简单方法限流实现

利用缓存通道写满时写阻塞, 为空时读阻塞的特性来实现

主要代码

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

func NowTimeStr() string {
const DateTimePattern = "2006-01-02 15:04:05"
return time.Now().Format(DateTimePattern)
}

type ERateLimiter struct {
c chan interface{}
tk *time.Ticker
}

// initFill 初始的并发数 , 每秒允许的并发数
func NewERateLimiter(initFill, requestPerSeconds int) *ERateLimiter {
//利用缓存通道写满时写阻塞, 为空时读阻塞的特性

limiter := ERateLimiter{}
concurrency := util.Max(initFill, requestPerSeconds)
limiter.c = make(chan interface{}, concurrency)
var i int
for i = 0; i < initFill; i++ {
limiter.c <- 0
}
sleept := 1000 / requestPerSeconds
limiter.tk = time.NewTicker(time.Millisecond * time.Duration(sleept))
limiter.Run()
return &limiter
}

func (receiver *ERateLimiter) Run() {

go func() {
for range receiver.tk.C {
receiver.c <- 0
}
}()
}


func (receiver *ERateLimiter) Stop() {
receiver.tk.Stop()
close(receiver.c)
}

func (receiver *ERateLimiter) Wait() {
<-receiver.c
}

测试

1
2
3
4
5
6
7
8
9
func TestERateLimiter(t *testing.T) {
limiter := NewERateLimiter(10, 10)
for i := 0; i < 50; i++ {
limiter.Wait()
fmt.Println(i+1, NowTimeStr())
}
limiter.Stop()
}

测试输出

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
52
53
54
=== RUN   TestERateLimiter
1 2021-02-19 11:56:48
2 2021-02-19 11:56:48
3 2021-02-19 11:56:48
4 2021-02-19 11:56:48
5 2021-02-19 11:56:48
6 2021-02-19 11:56:48
7 2021-02-19 11:56:48
8 2021-02-19 11:56:48
9 2021-02-19 11:56:48
10 2021-02-19 11:56:48
11 2021-02-19 11:56:48
12 2021-02-19 11:56:48
13 2021-02-19 11:56:48
14 2021-02-19 11:56:48
15 2021-02-19 11:56:48
16 2021-02-19 11:56:48
17 2021-02-19 11:56:48
18 2021-02-19 11:56:49
19 2021-02-19 11:56:49
20 2021-02-19 11:56:49
21 2021-02-19 11:56:49
22 2021-02-19 11:56:49
23 2021-02-19 11:56:49
24 2021-02-19 11:56:49
25 2021-02-19 11:56:49
26 2021-02-19 11:56:49
27 2021-02-19 11:56:49
28 2021-02-19 11:56:50
29 2021-02-19 11:56:50
30 2021-02-19 11:56:50
31 2021-02-19 11:56:50
32 2021-02-19 11:56:50
33 2021-02-19 11:56:50
34 2021-02-19 11:56:50
35 2021-02-19 11:56:50
36 2021-02-19 11:56:50
37 2021-02-19 11:56:50
38 2021-02-19 11:56:51
39 2021-02-19 11:56:51
40 2021-02-19 11:56:51
41 2021-02-19 11:56:51
42 2021-02-19 11:56:51
43 2021-02-19 11:56:51
44 2021-02-19 11:56:51
45 2021-02-19 11:56:51
46 2021-02-19 11:56:51
47 2021-02-19 11:56:51
48 2021-02-19 11:56:52
49 2021-02-19 11:56:52
50 2021-02-19 11:56:52
--- PASS: TestERateLimiter (4.00s)
PASS