go语言漏桶算法思路简单实现

Posted alxps

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了go语言漏桶算法思路简单实现相关的知识,希望对你有一定的参考价值。

package main

import (
	"fmt"
	"time"
)

// 桶
type LeakBucket struct {
	capacity       int           // 容量,固定时间语序访问次数
	interval       time.Duration // 允许访问的时间间隔
	dropsNum       int           // 固定时间访问了多少次
	lastAccessTime time.Time     // 最近一次的访问时间
}

func (b *LeakBucket) accessControl() bool {
	now := time.Now()
	pastTime := now.Sub(b.lastAccessTime)

	// 过去这段时间pastTime可以允许多少访问
	leaks := int(float64(pastTime) / float64(b.interval))
	if leaks > 0 { // 说明这段时间可以有leaks可以访问,但没有用户访问
		// 所以放宽访问,下一段访问限制减少一定leaks次限制,通过这种机制达到平滑控制流量
		if b.dropsNum <= leaks {
			b.dropsNum = 0
		} else {
			b.dropsNum -= leaks
		}
		// 更新访问时间
		b.lastAccessTime = now
	}

	if b.dropsNum < b.capacity { // 在允许访问之内
		b.dropsNum ++
		return true
	} else {
		return false
	}
}

func main() {
	bucket := &LeakBucket{
		capacity: 10,
		interval: time.Second,
	}

	for i := 0; i < 12; i++ {
		allowed := bucket.accessControl()
		fmt.Println("i",i)
		fmt.Println("i",allowed)
		time.Sleep(time.Millisecond * 500)
	}

	time.Sleep(time.Second*3) // 模拟3秒中时间内没有访问
	fmt.Println("空档期走完")

	for j := 0; j < 20; j++ {
		fmt.Println("BEFORE",bucket.dropsNum)
		allowed := bucket.accessControl()
		fmt.Println("AFTER",bucket.dropsNum)
		fmt.Println("j", j)
		fmt.Println("j",allowed)
		time.Sleep(time.Millisecond * 500)
	}
}

  

以上是关于go语言漏桶算法思路简单实现的主要内容,如果未能解决你的问题,请参考以下文章

RateLimiter

编程实践用 go 语言实现Bloom filter算法

限流算法之漏桶、令牌桶的区别

SpringBoot - 优雅的实现流控

冒泡排序之go语言实现

Go 语言入门很简单:实现 Vigenere 加密算法