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.
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.
go-zero code implementation
Go-zero uses redis expiration time to simulate a fixed time window.##core/limit/periodlimit.go
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 definitionPay attention to the align parameter, align= When true, the request upper limit will change periodically.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 } )
For example, when quota=5, the actual quota may be 5.4.3.2.1, showing periodic changes
Current limiting logicIn 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 } }
// 计算过期时间也就是窗口时间大小 // 如果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 addressgithub.com/zeromicro/go-zeroWelcome 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!

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

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

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

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

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

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


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

SublimeText3 English version
Recommended: Win version, supports code prompts!

VSCode Windows 64-bit Download
A free and powerful IDE editor launched by Microsoft

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
Useful JavaScript development tools

EditPlus Chinese cracked version
Small size, syntax highlighting, does not support code prompt function