Golang的几种限流 package的用法

这篇博客介绍了Golang中三种不同的限流包的使用方法,包括go.uber.org/ratelimit、golang.org/x/time/rate以及github.com/go-redis/redis_rate/v9。通过示例展示了如何限制每秒执行次数,并分析了它们在实际应用中的效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

go.uber.org/ratelimit

package rlimit

import (
    "fmt"
    "log"
    "testing"
    "time"

    "go.uber.org/ratelimit"
)

func TestRatelimit(t *testing.T) {
    rl := ratelimit.New(5) // per second

    log.Println("begin")
    prev := time.Now()
    for i := 0; i < 20; i++ {
        now := rl.Take()
        if i > 0 {
            fmt.Println(time.Now().String(), i, now.Sub(prev))
        }
        prev = now
    }

    log.Println("end")
}

运行结果:

[@hbhly_x_128 rlimit]$ go test -v ./
=== RUN   TestRatelimit
2022/03/26 16:57:41 begin
2022-03-26 16:57:42.014050639 +0800 CST m=+0.201108898 1 200ms
2022-03-26 16:57:42.21436404 +0800 CST m=+0.401422303 2 200ms
2022-03-26 16:57:42.415431893 +0800 CST m=+0.602490176 3 200ms
2022-03-26 16:57:42.613796177 +0800 CST m=+0.800854436 4 200ms
2022-03-26 16:57:42.813946371 +0800 CST m=+1.001004630 5 200ms
2022-03-26 16:57:43.014065797 +0800 CST m=+1.201124062 6 200ms
2022-03-26 16:57:43.213814857 +0800 CST m=+1.400873126 7 200ms
2022-03-26 16:57:43.414051201 +0800 CST m=+1.601109480 8 200ms
2022-03-26 16:57:43.614073789 +0800 CST m=+1.801132054 9 200ms
2022-03-26 16:57:43.815042061 +0800 CST m=+2.002100350 10 200ms
2022-03-26 16:57:44.013803537 +0800 CST m=+2.200861788 11 200ms
2022-03-26 16:57:44.213911271 +0800 CST m=+2.400969542 12 200ms
2022-03-26 16:57:44.413809965 +0800 CST m=+2.600868262 13 200ms
2022-03-26 16:57:44.613820171 +0800 CST m=+2.800878444 14 200ms
2022-03-26 16:57:44.813841891 +0800 CST m=+3.000900180 15 200ms
2022-03-26 16:57:45.013852437 +0800 CST m=+3.200910702 16 200ms
2022-03-26 16:57:45.213788735 +0800 CST m=+3.400846994 17 200ms
2022-03-26 16:57:45.414422254 +0800 CST m=+3.601480515 18 200ms
2022-03-26 16:57:45.613828739 +0800 CST m=+3.800887038 19 200ms
2022/03/26 16:57:45 end
--- PASS: TestRatelimit (3.80s)
PASS
ok      demo/rlimit     3.805s

说明:New 函数限制了每秒的执行个数(5),所以每个请求间隔200ms,然后我们发现执行总个数(20)需要的时间(4s) 

golang.org/x/time/rate

package rlimit

func TestRateLimiter(t *testing.T) {

    // 第一个参数是r Limit。代表每秒可以向Token桶中产生多少token
    // Limit实际上是float64的别名。

    // 第二个参数是b int。b代表Token桶的容量大小。
    //limiter := NewLimiter(10, 1);

    // 除了直接指定每秒产生的Token个数外,还可以用Every方法来指定向Token桶中放置Token的间隔
    // 例如:表示每100ms往桶中放一个Token。本质上也就是一秒钟产生10个:
    limit := Every(100 * time.Millisecond);
    limiter := NewLimiter(limit, 1);
}

github.com/go-redis/redis_rate/v9

package redis_rate_test

import (
	"context"
	"fmt"

	"github.com/go-redis/redis/v8"
	"github.com/go-redis/redis_rate/v9"
)

func ExampleNewLimiter() {
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr: "localhost:6379",
	})
	_ = rdb.FlushDB(ctx).Err()

	limiter := redis_rate.NewLimiter(rdb)
	res, err := limiter.Allow(ctx, "project:123", redis_rate.PerSecond(10))
	if err != nil {
		panic(err)
	}
	fmt.Println("allowed", res.Allowed, "remaining", res.Remaining)
	// Output: allowed 1 remaining 9
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值