前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >限流我使用time/rate,接入快代码少,谁用谁知道

限流我使用time/rate,接入快代码少,谁用谁知道

作者头像
小锟哥哥
发布2022-05-10 08:30:39
1850
发布2022-05-10 08:30:39
举报
文章被收录于专栏:GoLang全栈

关于限流

首先得知道什么是限流:

在日常生活中限流很常见,例如去有些景区玩,每天售卖的门票数是有限的。

例如 2000 张,即每天最多只有 2000 个人能进去游玩。

为什么这样做呢?

因为景区的管理员根据景区的各种参数,比如保安人数,比如景区面积等。

通过这些参数,来推导出这个景区一天最大能容纳多少人,于是就限定一天只卖这么多票。

我们程序也是同样的道理,我们得根据服务器的配置,你程序的性能综合评定,你每秒钟能处理多少请求。

从而对程序起到一定保护作用,不至于被一下涌来的大批量请求压垮我们的服务。

限流算法

限流算法有很多,主流的有两个分别是 令牌桶算法漏桶算法

今天要介绍的库 time/rate 是基于令牌桶算法编写的,所以漏桶算法先不做讲解。

什么是令牌桶算法?

我在百度百科上找了一张图,觉得比较形象,如下:

令牌桶算法的原理是系统以恒定的速率产生令牌,然后把令牌放到令牌桶中

令牌桶有一个容量,当令牌桶满了的时候,再向其中放令牌时多余的令牌就会被丢弃;

当想要处理一个请求的时候,需要从令牌桶中取出一个令牌,如果此时令牌桶中没有令牌,那么则拒绝该请求。

有点像生产者和消费者的关系,和最开始说的景区卖票很类似。

景区每24小时产生 2000 张票,然后给顾客消费,顾客来买票的时候,还有余票就可以进去,卖完了就不让进。

使用

我们使用的库是 go 官方的库,官方地址:golang.org/x/time/rate

此库只有两个文件,其中一个还是 test 测试文件。

安装

安装非常简单,直接 go get 就好了:

代码语言:javascript
复制
go get golang.org/x/time/rate

初始化

根据文档我们首先需要先定义投放速度和桶的容量,代码如下:

代码语言:javascript
复制
var r rate.Limit
var limit *rate.Limiter

func main() {

 // 一秒内产生10个令牌 1秒钟会执行10次 每次投放一个token
 r = rate.Every(1*time.Second)
 // 桶容量20个 预先缓冲20个
 limit = rate.NewLimiter(r,20)
}

随后我们就只需要通过 limit.AllowN(time.Now(),1) 去消费验证就可以了。

整合到 Gin

像这种验证性的代码,我们最好是放到中间件里面,于是我们的完整代码如下:

代码语言:javascript
复制
func Rate() gin.HandlerFunc {
 return func(c *gin.Context) {

  // AllowN 方法表示,截止到某一时刻,目前桶中数目是否至少为 n 个
  // 满足则返回 true,同时从桶中消费 n 个 token
  // 反之返回不消费 token,false
  // n 表示一次消费多少个
  if limit.AllowN(time.Now(),2) {
   log.Println("log:event happen")
   c.Next()
  }else{
   log.Println("log:event not allow")
   c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
    "code": 400,
   })
  }
 }
}

var r rate.Limit
var limit *rate.Limiter

func main() {

 // 一秒内产生10个令牌 1秒钟会执行10次 每次投放一个token
 r = rate.Every(100*time.Microsecond)
 // 桶容量20个 预先缓冲20个
 limit = rate.NewLimiter(r,20)

 r := gin.New()
 r.Use(Rate())

 r.Handle("GET","/", func(c *gin.Context) {
  c.JSON(http.StatusOK, gin.H{
   "code": 200,
  })
 })

 if err:=r.Run(":9083");err!=nil {
  panic(err)
 }
}

对于使用这个库了解这么多基本就可以了。

在测试时,你可以加大 limit.AllowN(time.Now(),2) 里面的 2,让他每次消费的令牌数量多一点,或者调整产生令牌的时间间隔变长一点,也能很快达到出现 400 的情况。

在如今的实际生产中,由程序去限流已经变得很少了,大都是由网关去处理限流,所以了解下原理再去了解网关的限流会更加容易些。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-10-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 GoLang全栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 关于限流
    • 为什么这样做呢?
    • 限流算法
      • 什么是令牌桶算法?
      • 使用
        • 安装
          • 初始化
            • 整合到 Gin
            相关产品与服务
            消息队列 TDMQ
            消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档