Merge pull request #194 from bilibili/library/bbr-prev-drop-optimization

修复自适应限流在 cpu 抖动后,可能出现限流过激的问题
pull/196/head
Tony 5 years ago committed by GitHub
commit a6cc978bdf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 14
      pkg/ratelimit/bbr/bbr.go
  2. 6
      pkg/ratelimit/bbr/bbr_test.go

@ -17,10 +17,10 @@ import (
var ( var (
cpu int64 cpu int64
decay = 0.75 decay = 0.95
defaultConf = &Config{ defaultConf = &Config{
Window: time.Second * 5, Window: time.Second * 10,
WinBucket: 50, WinBucket: 100,
CPUThreshold: 800, CPUThreshold: 800,
} }
) )
@ -31,6 +31,7 @@ func init() {
go cpuproc() go cpuproc()
} }
// cpu = cpuᵗ⁻¹ * decay + cpuᵗ * (1 - decay)
func cpuproc() { func cpuproc() {
ticker := time.NewTicker(time.Millisecond * 250) ticker := time.NewTicker(time.Millisecond * 250)
defer func() { defer func() {
@ -136,7 +137,11 @@ func (l *BBR) shouldDrop() bool {
} }
return false return false
} }
return inFlight > 1 && inFlight > maxInflight drop := inFlight > 1 && inFlight > maxInflight
if drop {
atomic.StoreInt64(&l.prevDrop, time.Now().Unix())
}
return drop
} }
// Stat tasks a snapshot of the bbr limiter. // Stat tasks a snapshot of the bbr limiter.
@ -158,7 +163,6 @@ func (l *BBR) Allow(ctx context.Context, opts ...limit.AllowOption) (func(info l
opt.Apply(&allowOpts) opt.Apply(&allowOpts)
} }
if l.shouldDrop() { if l.shouldDrop() {
atomic.StoreInt64(&l.prevDrop, time.Now().Unix())
return nil, ecode.LimitExceed return nil, ecode.LimitExceed
} }
atomic.AddInt64(&l.inFlight, 1) atomic.AddInt64(&l.inFlight, 1)

@ -145,7 +145,13 @@ func TestBBRShouldDrop(t *testing.T) {
bbr.inFlight = 80 bbr.inFlight = 80
assert.Equal(t, true, bbr.shouldDrop()) assert.Equal(t, true, bbr.shouldDrop())
// cpu < 800, inflight > maxQps, cold duration
cpu = 700
bbr.inFlight = 80
assert.Equal(t, true, bbr.shouldDrop())
// cpu < 800, inflight > maxQps // cpu < 800, inflight > maxQps
time.Sleep(2 * time.Second)
cpu = 700 cpu = 700
bbr.inFlight = 80 bbr.inFlight = 80
assert.Equal(t, false, bbr.shouldDrop()) assert.Equal(t, false, bbr.shouldDrop())

Loading…
Cancel
Save