• Token Bucket Algorithm


    Reference

    Token bucket

    Over the long run the output of conformant packets is limited by the token rate, ({displaystyle r}).

    Implementation

    package main
    
    import (
    	"os"
    	"sync"
    	"time"
    
    	logger "github.com/sirupsen/logrus"
    	"github.com/x-cray/logrus-prefixed-formatter"
    )
    
    func init() {
    	logger.SetFormatter(&prefixed.TextFormatter{
    		TimestampFormat: "2006-01-02 15:04:05",
    		FullTimestamp:   true,
    		ForceFormatting: true,
    		DisableColors:   true,
    	})
    	logger.SetOutput(os.Stdout)
    	logger.SetLevel(logger.DebugLevel)
    }
    
    type TokenBucket struct {
    	mu              sync.Mutex
    	startTime       time.Time
    	availableTokens int64
    	capacity        int64
    	fillInterval    time.Duration
    	lastTick        int64
    }
    
    func NewTokenBucket(qps, capacity int64) *TokenBucket {
    	return &TokenBucket{
    		startTime:       time.Now(),
    		availableTokens: capacity,
    		capacity:        capacity,
    		lastTick:        0,
    		fillInterval:    time.Duration(int64(time.Second) / qps),
    	}
    }
    
    func (tb *TokenBucket) adjust() {
    	if (tb.availableTokens) >= tb.capacity {
    		return
    	}
    	now := time.Now()
    	tick := int64(now.Sub(tb.startTime) / tb.fillInterval)
    	tb.availableTokens += tick - tb.lastTick
    	if tb.availableTokens > tb.capacity {
    		tb.availableTokens = tb.capacity
    	}
    	tb.lastTick = tick
    }
    
    func (tb *TokenBucket) TakeAvailable(count int64) int64 {
    	tb.mu.Lock()
    	defer tb.mu.Unlock()
    
    	tb.adjust()
    
    	if tb.availableTokens <= 0 {
    		return 0
    	}
    
    	if count >= tb.availableTokens {
    		count = tb.availableTokens
    	}
    
    	tb.availableTokens -= count
    	return count
    }
    
    func task(qps, num int64, timeNeed time.Duration) {
    	logger.Infof("task qps: %v, num: %v, timeNeed: %.3fs", qps, num, timeNeed.Seconds())
    	bucket := NewTokenBucket(qps, qps)
    	startTime := time.Now()
    	lastTime := startTime
    
    	for i := int64(1); i <= num; {
    		if bucket.TakeAvailable(1) == 1 {
    			time.Sleep(timeNeed)
    			i++
    			if i%1000 == 0 {
    				now := time.Now()
    				logger.Infof("rate: %.3f", 1000/now.Sub(lastTime).Seconds())
    				lastTime = now
    			}
    		}
    	}
    
    	logger.Infof("task over, used: %.3fs", time.Now().Sub(startTime).Seconds())
    }
    
    func main() {
    	task(10000, 100000, 0)
    	task(10000, 15000, 2*time.Millisecond)
    	task(500, 10000, 0)
    }
    
    [2020-03-31 15:58:49]  INFO task qps: 10000, num: 100000, timeNeed: 0.000s
    [2020-03-31 15:58:49]  INFO rate: 6698910.757
    [2020-03-31 15:58:49]  INFO rate: 6132110.182
    [2020-03-31 15:58:49]  INFO rate: 6394802.305
    [2020-03-31 15:58:49]  INFO rate: 6386511.687
    [2020-03-31 15:58:49]  INFO rate: 5484591.041
    [2020-03-31 15:58:49]  INFO rate: 6646770.666
    [2020-03-31 15:58:49]  INFO rate: 5725671.621
    [2020-03-31 15:58:49]  INFO rate: 6449490.813
    [2020-03-31 15:58:49]  INFO rate: 5718631.875
    [2020-03-31 15:58:49]  INFO rate: 6620981.892
    [2020-03-31 15:58:49]  INFO rate: 10174.362
    [2020-03-31 15:58:49]  INFO rate: 9999.993
    [2020-03-31 15:58:49]  INFO rate: 9999.979
    [2020-03-31 15:58:49]  INFO rate: 10000.032
    [2020-03-31 15:58:49]  INFO rate: 9999.993
    [2020-03-31 15:58:49]  INFO rate: 10000.001
    [2020-03-31 15:58:50]  INFO rate: 9999.981
    [2020-03-31 15:58:50]  INFO rate: 9750.039
    [2020-03-31 15:58:50]  INFO rate: 10263.124
    [2020-03-31 15:58:50]  INFO rate: 10000.008
    [2020-03-31 15:58:50]  INFO rate: 10000.004
    [2020-03-31 15:58:50]  INFO rate: 10000.006
    [2020-03-31 15:58:50]  INFO rate: 9999.980
    [2020-03-31 15:58:50]  INFO rate: 10000.013
    [2020-03-31 15:58:50]  INFO rate: 10000.008
    [2020-03-31 15:58:50]  INFO rate: 9999.989
    [2020-03-31 15:58:51]  INFO rate: 10000.006
    [2020-03-31 15:58:51]  INFO rate: 10000.002
    [2020-03-31 15:58:51]  INFO rate: 10000.002
    [2020-03-31 15:58:51]  INFO rate: 9999.990
    [2020-03-31 15:58:51]  INFO rate: 9999.990
    [2020-03-31 15:58:51]  INFO rate: 10000.004
    [2020-03-31 15:58:51]  INFO rate: 10000.008
    [2020-03-31 15:58:51]  INFO rate: 10000.004
    [2020-03-31 15:58:51]  INFO rate: 9999.999
    [2020-03-31 15:58:51]  INFO rate: 9999.994
    [2020-03-31 15:58:52]  INFO rate: 10000.011
    [2020-03-31 15:58:52]  INFO rate: 9999.991
    [2020-03-31 15:58:52]  INFO rate: 9865.780
    [2020-03-31 15:58:52]  INFO rate: 10137.923
    [2020-03-31 15:58:52]  INFO rate: 9999.998
    [2020-03-31 15:58:52]  INFO rate: 10000.009
    [2020-03-31 15:58:52]  INFO rate: 10000.000
    [2020-03-31 15:58:52]  INFO rate: 9999.998
    [2020-03-31 15:58:52]  INFO rate: 10000.000
    [2020-03-31 15:58:52]  INFO rate: 10000.000
    [2020-03-31 15:58:53]  INFO rate: 10000.002
    [2020-03-31 15:58:53]  INFO rate: 10000.006
    [2020-03-31 15:58:53]  INFO rate: 9999.994
    [2020-03-31 15:58:53]  INFO rate: 9999.992
    [2020-03-31 15:58:53]  INFO rate: 9999.989
    [2020-03-31 15:58:53]  INFO rate: 10000.026
    [2020-03-31 15:58:53]  INFO rate: 9999.996
    [2020-03-31 15:58:53]  INFO rate: 10000.001
    [2020-03-31 15:58:53]  INFO rate: 9999.975
    [2020-03-31 15:58:53]  INFO rate: 10000.015
    [2020-03-31 15:58:54]  INFO rate: 10000.008
    [2020-03-31 15:58:54]  INFO rate: 9999.993
    [2020-03-31 15:58:54]  INFO rate: 10000.011
    [2020-03-31 15:58:54]  INFO rate: 9998.373
    [2020-03-31 15:58:54]  INFO rate: 10001.612
    [2020-03-31 15:58:54]  INFO rate: 10000.003
    [2020-03-31 15:58:54]  INFO rate: 10000.010
    [2020-03-31 15:58:54]  INFO rate: 10000.000
    [2020-03-31 15:58:54]  INFO rate: 10000.000
    [2020-03-31 15:58:54]  INFO rate: 9999.988
    [2020-03-31 15:58:55]  INFO rate: 10000.005
    [2020-03-31 15:58:55]  INFO rate: 10000.007
    [2020-03-31 15:58:55]  INFO rate: 9999.996
    [2020-03-31 15:58:55]  INFO rate: 9999.999
    [2020-03-31 15:58:55]  INFO rate: 9999.976
    [2020-03-31 15:58:55]  INFO rate: 10000.032
    [2020-03-31 15:58:55]  INFO rate: 9999.998
    [2020-03-31 15:58:55]  INFO rate: 10000.000
    [2020-03-31 15:58:55]  INFO rate: 9999.990
    [2020-03-31 15:58:55]  INFO rate: 10000.001
    [2020-03-31 15:58:56]  INFO rate: 9999.999
    [2020-03-31 15:58:56]  INFO rate: 9999.993
    [2020-03-31 15:58:56]  INFO rate: 10000.012
    [2020-03-31 15:58:56]  INFO rate: 10000.001
    [2020-03-31 15:58:56]  INFO rate: 10000.005
    [2020-03-31 15:58:56]  INFO rate: 9999.996
    [2020-03-31 15:58:56]  INFO rate: 9999.993
    [2020-03-31 15:58:56]  INFO rate: 9999.999
    [2020-03-31 15:58:56]  INFO rate: 10000.008
    [2020-03-31 15:58:56]  INFO rate: 9999.996
    [2020-03-31 15:58:57]  INFO rate: 9998.998
    [2020-03-31 15:58:57]  INFO rate: 10001.010
    [2020-03-31 15:58:57]  INFO rate: 9999.992
    [2020-03-31 15:58:57]  INFO rate: 10000.004
    [2020-03-31 15:58:57]  INFO rate: 9999.997
    [2020-03-31 15:58:57]  INFO rate: 9999.988
    [2020-03-31 15:58:57]  INFO rate: 10000.012
    [2020-03-31 15:58:57]  INFO rate: 9999.996
    [2020-03-31 15:58:57]  INFO rate: 10000.012
    [2020-03-31 15:58:57]  INFO rate: 9999.998
    [2020-03-31 15:58:58]  INFO rate: 9999.991
    [2020-03-31 15:58:58]  INFO rate: 9999.990
    [2020-03-31 15:58:58]  INFO rate: 10000.020
    [2020-03-31 15:58:58]  INFO rate: 9999.995
    [2020-03-31 15:58:58]  INFO task over, used: 9.000s
    [2020-03-31 15:58:58]  INFO task qps: 10000, num: 15000, timeNeed: 0.002s
    [2020-03-31 15:59:00]  INFO rate: 397.098
    [2020-03-31 15:59:03]  INFO rate: 396.814
    [2020-03-31 15:59:05]  INFO rate: 397.583
    [2020-03-31 15:59:08]  INFO rate: 391.641
    [2020-03-31 15:59:10]  INFO rate: 391.799
    [2020-03-31 15:59:13]  INFO rate: 400.202
    [2020-03-31 15:59:15]  INFO rate: 402.581
    [2020-03-31 15:59:18]  INFO rate: 405.188
    [2020-03-31 15:59:20]  INFO rate: 396.681
    [2020-03-31 15:59:23]  INFO rate: 397.131
    [2020-03-31 15:59:25]  INFO rate: 398.076
    [2020-03-31 15:59:28]  INFO rate: 398.811
    [2020-03-31 15:59:30]  INFO rate: 399.199
    [2020-03-31 15:59:33]  INFO rate: 400.549
    [2020-03-31 15:59:36]  INFO rate: 390.775
    [2020-03-31 15:59:36]  INFO task over, used: 37.732s
    [2020-03-31 15:59:36]  INFO task qps: 500, num: 10000, timeNeed: 0.000s
    [2020-03-31 15:59:37]  INFO rate: 1002.004
    [2020-03-31 15:59:39]  INFO rate: 500.000
    [2020-03-31 15:59:41]  INFO rate: 500.000
    [2020-03-31 15:59:43]  INFO rate: 500.000
    [2020-03-31 15:59:45]  INFO rate: 500.000
    [2020-03-31 15:59:47]  INFO rate: 500.000
    [2020-03-31 15:59:49]  INFO rate: 500.000
    [2020-03-31 15:59:51]  INFO rate: 500.000
    [2020-03-31 15:59:53]  INFO rate: 500.000
    [2020-03-31 15:59:55]  INFO rate: 500.000
    [2020-03-31 15:59:55]  INFO task over, used: 19.000s
    
  • 相关阅读:
    在VMware中为Red Hat配置静态ip并可访问网络-Windows下的VMware
    03-nginx虚拟主机配置
    解决nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
    02-nginx信号量
    RedHat Linux设置yum软件源为本地ISO
    01-nginx介绍及编译安装
    Linux.负载均衡
    01-MySQL优化大的思路
    10 华电内部文档搜索系统 search02
    10 华电内部文档搜索系统 search03
  • 原文地址:https://www.cnblogs.com/ToRapture/p/12605850.html
Copyright © 2020-2023  润新知