Go限流算法-漏斗算法

/ 0评 / 0

之前一直要整理Go语言的漏斗限流算法,不过最近一直在看Redis和MySQL的课程,文档整理有些疏忽了。还是要多努力!!

先直接上代码

package main

import (
	"fmt"
	"time"
)

type LeakyBucket struct {
	leakingTime time.Time //上一次漏水时间
	capacity    float64   // 漏斗容量
	leakingRate float64   //漏嘴流水速率
	leftQuota   float64   //漏斗剩余空间
}

func main() {
	
	bucket := &LeakyBucket{}
	bucket.leakingTime = time.Now()
	time.Sleep(time.Second)
	bucket.makeSpace()
}
func (bucket *LeakyBucket)makeSpace() {
	nowTs := time.Now()
	//返回距离上一次漏水经过了多长时间,结果是秒
	deltaTs := nowTs.Sub(bucket.leakingTime).Seconds()
	//计算又可以腾出来多少空间
	deltaQuota := deltaTs * bucket.leakingRate
	if deltaQuota < 1 {
		//如果腾出来的空间太少,则丢次此次请求
		return
	}
	//增加剩余空间
	bucket.leftQuota += deltaQuota
	//记录流水时间
	bucket.leakingTime = nowTs
	if bucket.leftQuota > bucket.capacity {
		//剩余空间不得高于容量
		bucket.leftQuota = bucket.capacity
	}
}

func (bucket *LeakyBucket)watering(quota float64) bool {
	bucket.makeSpace()
	//判断剩余空间是否足够
	if bucket.leftQuota >= quota {
		bucket.leftQuota -= quota
		return true
	}
	return false
}
var funnels = make(map[string]LeakyBucket)
//是否允许操作存储桶
func (bucket *LeakyBucket)isActionAllowedBucket(userId,actionKey string,capacity,leakingRate float64) bool  {
	//格式化key
	key := fmt.Sprintf("%s_%s",userId,actionKey)
	funnel,ok := funnels[key]
	if !ok {
		//如果funnels能找到key
		funnel.capacity = capacity
		funnel.leakingRate = leakingRate
	}
	return bucket.watering(1.0)
}

本文参考过网上一些其它文章,后又在自己的理解上做了修改和整理。如有问题可联系:houzhenkai@houzhenkai.com