go-zero中限流怎么玩?

限流

在大部分应用中,为了对服务进行保护,我们通常都会添加限流策略,比如:限制同一用户一段时间内验证码的发送频率、开放API平台,限制每个应用在单位时间内的API调用次数、单节点限制最大并发数据,防止压垮服务等等。

今天我们一起来看看在go-zero中限流怎么玩?

go-zero中的限流主要有三种,我们依次看下。

一、 配置MaxConns

它是一种http单节点的限流,它限制的是当前节点的并发量(并发数)

它**最简单,只需要我们在api模块下的etc目录配置MaxConns**就行,其它啥也不用做,如下:

yaml 复制代码
Name: limit

Host: 0.0.0.0

Port: 8888

MaxConns: 100

PS: 默认情况下MaxConns为10000.

原理

它是通过syncx.Limit实现的。

它的机制是一种连接池机制,一开始有一个池,这个池子有一个最大的并发量。

  • 每次请会先从池子借用一个连接

  • 使用完后归还连接

当全部借出后,则不再处理请求,提示(concurrent connections over ...).

它的使用非常简单,就是三步:

  1. 初始化池子(sync.Limit)

  2. 借用

  3. 归还

代码如下:

go 复制代码
package main

  


import (

"fmt"

"log"

  


"github.com/zeromicro/go-zero/core/syncx"

)

  


func main() {

limit := syncx.NewLimit(2)

  


if limit.TryBorrow() {

fmt.Println("借用成功啦")

} else {

fmt.Println("借用失败")

}

  


err := limit.Return()

if err != nil {

log.Println("归还失败:", err)

} else {

fmt.Println("归还成功")

}

}

二、令牌通限流

上面我们已经介绍了针对于http请求场景的单节点限流,它的粒度相对较大。在一些其它场景还是不能满足我们的要求。

比如:比如我们希望对某一个细分模块限流,比如发送短信模块,我们希望每秒内最多发送100条短信,那么我们就可以使用令牌桶限流。

它限制的是:每秒内的发生频率,且支持一个范围,一个最小值和一个最大值------应对突发情况.

PS:它的使用要复杂点,依赖于redis

代码:

go 复制代码
package main

  


import (

"fmt"

  


"github.com/zeromicro/go-zero/core/limit"

"github.com/zeromicro/go-zero/core/stores/redis"

)

  


func main() {

store, err := redis.NewRedis(redis.RedisConf{Host: "127.0.0.1:6379", Type: "node"})

if err != nil {

panic(err)

}

  


// 每秒中内 可以处理 5-10个请求(最大20个超过就爆掉)

// example-key 是redis中标记(或者限制模块的key)

limiter := limit.NewTokenLimiter(5, 10, store, "example-key")

  


// 我们测试

for i := 0; i < 20; i++ {

// 是否允许

if limiter.Allow() {

fmt.Println("Request allowed") // 前10个成功

} else {

fmt.Println("Request not allowed") // 后10个失败

}

}

}

  


// Request allowed

// Request allowed

// Request allowed

// Request allowed

// Request allowed

// Request allowed

// Request allowed

// Request allowed

// Request allowed

// Request allowed

// Request not allowed

// Request not allowed

// Request not allowed

// Request not allowed

// Request not allowed

// Request not allowed

// Request not allowed

// Request not allowed

// Request not allowed

// Request not allowed

前10个请求成功,后10个请求失败,符合我们的预期。

三、计数器(时间内限流)

前面我们限制的是1s内处理数,但是在很多场景下,通常我们限制的是一个时间范围内的请求次数

比如:一个用户在一分钟内,只能获取2次验证码。

它通常是更细分、用户级的限流

它也依赖于redis

它的使用大体和令牌桶类似,只是它的参数不同,如下:

go 复制代码
package main

  


import (

"fmt"

  


"github.com/zeromicro/go-zero/core/limit"

"github.com/zeromicro/go-zero/core/stores/redis"

)

  


func main() {

store, err := redis.NewRedis(redis.RedisConf{Host: "127.0.0.1:6379", Type: "node"})

if err != nil {

panic(err)

}

  


// 这里限制60秒内 最多允许2次

// 注意这里的exampleKey只是一个前缀(具体的key后半部分由场景决定)

limiter := limit.NewPeriodLimit(60, 2, store, "exampleKey")

  


for i := 0; i < 10; i++ {

// 这里的限制用户的请求次数

result, err := limiter.Take("userId")

if err != nil {

fmt.Println("Error:", err)

return

}

  


switch result {

case limit.Allowed:

fmt.Println("Request allowed")

case limit.HitQuota: // 代表达到临界点(下一次就超了)

fmt.Println("Hit the quota")

case limit.OverQuota:

fmt.Println("Over the quota")

default:

fmt.Println("Unknown status")

}

}

}

  


// Request allowed

// Hit the quota

// Over the quota

// Over the quota

// Over the quota

// Over the quota

// Over the quota

// Over the quota

// Over the quota

// Over the quota
相关推荐
SoStraw1 分钟前
Go + webrpc 实战:人在外面,远程查家里 NAS 磁盘和目录
go·p2p·nas·cgo·json-rpc·webrpc·无公网ip
小蒜学长12 分钟前
“喵汪联盟”宠物领养系统的设计与实现(代码+数据库+LW)
java·spring boot·后端·宠物
SomeB1oody18 分钟前
【RustyML入门】3.7. 循环层
开发语言·后端·机器学习·rust·教程
东风破_10 小时前
ESLint 是什么?为什么你的项目需要它?
前端·后端·代码规范
嘻哈∠※10 小时前
0061基于 SpringBoot 的投稿与稿件处理系统设计与实现
java·spring boot·后端
卷无止境11 小时前
在 awesome-fastapi 里,哪些库值得一看?
后端·python
卷无止境12 小时前
FastAPI 的Admin面板生态
后端·python
捡田螺的小男孩13 小时前
什么是 Skill?手把手带你写一个简单有用的 Skill!
前端·后端·程序员
IT_陈寒13 小时前
Redis集群这个坑,差点让我通宵
前端·人工智能·后端
用户83562907805114 小时前
Python 自动化 Word 文本框处理:创建、定位、填充内容与管理
后端·python