search
HomeBackend DevelopmentGolangHow to implement user daily limit in Go
How to implement user daily limit in GoJan 10, 2022 pm 03:55 PM
gogo-zeromicroservices

This article is written by the golang tutorial column to introduce how to implement the user's daily limit in Go. I hope it will be helpful to friends in need!

Implement the user’s daily limit in Go (for example, you can only receive benefits three times a day)

If you write a bug management system and use this PeriodLimit, you can limit each tester to only submit one bug to you per day. Is work much easier? :P

The essential reason why microservice architecture is so popular nowadays is to reduce the overall complexity of the system, evenly distribute system risks to subsystems to maximize the stability of the system, and split it into different systems through domain division. After the subsystems are installed, each subsystem can be independently developed, tested, and released, and the R&D rhythm and efficiency can be significantly improved.

But it also brings problems, such as: the calling link is too long, the complexity of the deployment architecture increases, and various middleware needs to support distributed scenarios. In order to ensure the normal operation of microservices, service governance is indispensable, which usually includes: current limiting, downgrading, and circuit breaker.

Current limiting refers to limiting the frequency of interface calls to avoid exceeding the load limit and bringing down the system. For example:

  • E-commerce Flash Sale Scenario

  • API current limit for different merchants

Commonly used The current limiting algorithms are:

  • Fixed time window current limiting
  • Sliding time window current limiting
  • Leaky bucket current limiting
  • Token bucket limited Flow

This article mainly explains the fixed time window current limiting algorithm.

Working Principle

Starting from a certain point in time, each request comes with a request count of 1. At the same time, it is judged whether the number of requests in the current time window exceeds the limit. If it exceeds the limit, it will be rejected. The request is then cleared when the next time window begins waiting for the request.

How to implement user daily limit in Go

Advantages and Disadvantages

Advantages

Easy to implement It is efficient and is especially suitable for limiting scenarios such as a user can only post 10 articles a day, can only send SMS verification codes 5 times, and can only try to log in 5 times. Such scenarios are very common in actual business.

Disadvantages

The disadvantage of fixed time window current limiting is that it cannot handle critical section request burst scenarios.

Assume that the current limit is 100 requests every 1 second, and the user initiates 200 requests within 1 second starting from the middle 500ms. At this time, all 200 requests can be passed. This is inconsistent with our expectation of limiting the current to 100 times per second. The root cause is that the fine-grainedness of the current limit is too coarse.

How to implement user daily limit in Go

go-zero code implementation

##core/limit/periodlimit.go

Go-zero uses redis expiration time to simulate a fixed time window.

redis lua script:

-- KYES[1]:限流器key-- ARGV[1]:qos,单位时间内最多请求次数-- ARGV[2]:单位限流窗口时间-- 请求最大次数,等于p.quotalocal limit = tonumber(ARGV[1])-- 窗口即一个单位限流周期,这里用过期模拟窗口效果,等于p.permitlocal window = tonumber(ARGV[2])-- 请求次数+1,获取请求总数local current = redis.call("INCRBY",KYES[1],1)-- 如果是第一次请求,则设置过期时间并返回 成功if current == 1 then
  redis.call("expire",KYES[1],window)
  return 1-- 如果当前请求数量小于limit则返回 成功elseif current limit则返回 失败else
  return 0end
Fixed time window current limiter definition

type (
  // PeriodOption defines the method to customize a PeriodLimit.
  // go中常见的option参数模式
  // 如果参数非常多,推荐使用此模式来设置参数
  PeriodOption func(l *PeriodLimit)

  // A PeriodLimit is used to limit requests during a period of time.
  // 固定时间窗口限流器
  PeriodLimit struct {
    // 窗口大小,单位s
    period     int
    // 请求上限
    quota      int
    // 存储
    limitStore *redis.Redis
    // key前缀
    keyPrefix  string
    // 线性限流,开启此选项后可以实现周期性的限流
    // 比如quota=5时,quota实际值可能会是5.4.3.2.1呈现出周期性变化
    align      bool
  }
)
Pay attention to the align parameter, align= When true, the request upper limit will change periodically.

For example, when quota=5, the actual quota may be 5.4.3.2.1, showing periodic changes

Current limiting logic

In fact, the current limiting logic is above The lua script is implemented. It should be noted that the return value

    0: indicates an error, such as redis failure or overload
  • 1: allowed
  • 2: allowed However, the upper limit has been reached in the current window. If you are running a batch business, you can sleep and wait for the next window (the author has considered it very carefully)
  • 3: Rejection
  • // Take requests a permit, it returns the permit state.
    // 执行限流
    // 注意一下返回值:
    // 0:表示错误,比如可能是redis故障、过载
    // 1:允许
    // 2:允许但是当前窗口内已到达上限
    // 3:拒绝
    func (h *PeriodLimit) Take(key string) (int, error) {
      // 执行lua脚本
      resp, err := h.limitStore.Eval(periodScript, []string{h.keyPrefix + key}, []string{
        strconv.Itoa(h.quota),
        strconv.Itoa(h.calcExpireSeconds()),
      })
    
      if err != nil {
        return Unknown, err
      }
    
      code, ok := resp.(int64)
      if !ok {
        return Unknown, ErrUnknownCode
      }
    
      switch code {
      case internalOverQuota:
        return OverQuota, nil
      case internalAllowed:
        return Allowed, nil
      case internalHitQuota:
        return HitQuota, nil
      default:
        return Unknown, ErrUnknownCode
      }
    }
This fixed window current limit may be used to limit, for example, a user can only send verification code text messages 5 times a day. At this time, we need to correspond to the Chinese time zone (GMT 8), and in fact, the current limit time should start from zero o'clock. At this time, we need Additional alignment (set align to true).

// 计算过期时间也就是窗口时间大小
// 如果align==true
// 线性限流,开启此选项后可以实现周期性的限流
// 比如quota=5时,quota实际值可能会是5.4.3.2.1呈现出周期性变化
func (h *PeriodLimit) calcExpireSeconds() int {
  if h.align {
    now := time.Now()
    _, offset := now.Zone()
    unix := now.Unix() + int64(offset)
    return h.period - int(unix%int64(h.period))
  }

  return h.period
}

Project address

github.com/zeromicro/go-zero

Welcome to use

go-zero and star support us!

The above is the detailed content of How to implement user daily limit in Go. For more information, please follow other related articles on the PHP Chinese website!

Statement
This article is reproduced at:learnku. If there is any infringement, please contact admin@php.cn delete
go语言有没有缩进go语言有没有缩进Dec 01, 2022 pm 06:54 PM

go语言有缩进。在go语言中,缩进直接使用gofmt工具格式化即可(gofmt使用tab进行缩进);gofmt工具会以标准样式的缩进和垂直对齐方式对源代码进行格式化,甚至必要情况下注释也会重新格式化。

go语言为什么叫gogo语言为什么叫goNov 28, 2022 pm 06:19 PM

go语言叫go的原因:想表达这门语言的运行速度、开发速度、学习速度(develop)都像gopher一样快。gopher是一种生活在加拿大的小动物,go的吉祥物就是这个小动物,它的中文名叫做囊地鼠,它们最大的特点就是挖洞速度特别快,当然可能不止是挖洞啦。

一文浅析Golang中的闭包一文浅析Golang中的闭包Nov 21, 2022 pm 08:36 PM

闭包(closure)是一个函数以及其捆绑的周边环境状态(lexical environment,词法环境)的引用的组合。 换而言之,闭包让开发者可以从内部函数访问外部函数的作用域。 闭包会随着函数的创建而被同时创建。

聊聊Golang中的几种常用基本数据类型聊聊Golang中的几种常用基本数据类型Jun 30, 2022 am 11:34 AM

本篇文章带大家了解一下golang 的几种常用的基本数据类型,如整型,浮点型,字符,字符串,布尔型等,并介绍了一些常用的类型转换操作。

一文详解Go中的并发【20 张动图演示】一文详解Go中的并发【20 张动图演示】Sep 08, 2022 am 10:48 AM

Go语言中各种并发模式看起来是怎样的?下面本篇文章就通过20 张动图为你演示 Go 并发,希望对大家有所帮助!

【整理分享】一些GO面试题(附答案解析)【整理分享】一些GO面试题(附答案解析)Oct 25, 2022 am 10:45 AM

本篇文章给大家整理分享一些GO面试题集锦快答,希望对大家有所帮助!

tidb是go语言么tidb是go语言么Dec 02, 2022 pm 06:24 PM

是,TiDB采用go语言编写。TiDB是一个分布式NewSQL数据库;它支持水平弹性扩展、ACID事务、标准SQL、MySQL语法和MySQL协议,具有数据强一致的高可用特性。TiDB架构中的PD储存了集群的元信息,如key在哪个TiKV节点;PD还负责集群的负载均衡以及数据分片等。PD通过内嵌etcd来支持数据分布和容错;PD采用go语言编写。

go语言是否需要编译go语言是否需要编译Dec 01, 2022 pm 07:06 PM

go语言需要编译。Go语言是编译型的静态语言,是一门需要编译才能运行的编程语言,也就说Go语言程序在运行之前需要通过编译器生成二进制机器码(二进制的可执行文件),随后二进制文件才能在目标机器上运行。

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

SublimeText3 English version

SublimeText3 English version

Recommended: Win version, supports code prompts!

VSCode Windows 64-bit Download

VSCode Windows 64-bit Download

A free and powerful IDE editor launched by Microsoft

MantisBT

MantisBT

Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools

EditPlus Chinese cracked version

EditPlus Chinese cracked version

Small size, syntax highlighting, does not support code prompt function