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
相关推荐
有来技术2 小时前
Spring Boot 4 + Vue3 企业级多租户 SaaS:从共享 Schema 架构到商业化套餐设计
java·vue.js·spring boot·后端
东东5163 小时前
学院个人信息管理系统 (springboot+vue)
vue.js·spring boot·后端·个人开发·毕设
三水不滴3 小时前
Redis缓存更新策略
数据库·经验分享·redis·笔记·后端·缓存
小邓吖4 小时前
自己做了一个工具网站
前端·分布式·后端·中间件·架构·golang
大爱编程♡4 小时前
SpringBoot统一功能处理
java·spring boot·后端
码界奇点6 小时前
基于Gin与GORM的若依后台管理系统设计与实现
论文阅读·go·毕业设计·gin·源代码管理
迷迭香与樱花7 小时前
Gin 框架
go·gin
好好研究7 小时前
总结SSM设置欢迎页的方式
xml·java·后端·mvc
小马爱打代码7 小时前
Spring Boot:第三方 API 调用的企业级容错设计
java·spring boot·后端
csdn2015_9 小时前
springboot task
java·spring boot·后端