Go语言极简实现限流器!高并发接口必备,8行代码搞定流量削峰
·
2026年云原生岗位持续扩招,Go语言依旧是后端高薪首选技术栈,而接口限流、流量削峰是Go后端面试必问、项目必用的核心功能。
很多新手一听到限流,就想到Redis分布式限流、复杂的令牌桶/漏桶算法,觉得实现难度极高。其实在单机接口场景下,无需引入第三方中间件,8行核心Go代码即可实现标准令牌桶限流,开箱即用,直接嵌入Gin、Echo任意Web框架。
本文不讲晦涩理论,直接落地实战,先讲限流应用场景,再贴极简代码,最后讲解源码原理,同时对比漏桶与令牌桶的选型区别,适合面试突击、项目开发直接复用。(全文约1510字)
一、为什么后端接口必须做限流?
线上服务随时会面临突发流量:爬虫恶意刷接口、活动秒杀瞬时峰值、用户集中请求。如果不做限流保护,会直接导致服务CPU打满、数据库连接池耗尽、整个服务雪崩。
目前主流两种限流算法:
- 漏桶算法:流量匀速流出,适合控制接口处理速度,不允许突发流量
- 令牌桶算法:匀速生成令牌,允许少量突发流量,适配秒杀、活动接口(后端90%场景首选)
二、8行核心Go代码实现单机令牌桶限流器
不依赖任何第三方库,原生Go标准库实现,代码极简,通俗易懂:
package main
import (
nc"
ime"
)
// TokenBucket 令牌桶结构体
type TokenBucket struct {
acity int // 桶最大容量
tokenNum int // 当前令牌数量
ate int // 每秒生成令牌数
tTime time.Time // 上次发放令牌时间
sync.Mutex // 互斥锁,保证并发安全
}
// NewTokenBucket 初始化令牌桶
func NewTokenBucket(capacity, rate int) *TokenBucket {
return &TokenBucket{
capacity: capacity,
tokenNum: capacity,
rate: rate,
tTime: time.Now(),
}
// Allow 请求是否放行,核心8行逻辑
func (t *TokenBucket) Allow() bool {
.Lock()
defer t.mu.Unlock()
/ 计算时间差,补充令牌
w := time.Now()
elta := int(now.Sub(t.lastTime).Seconds())
tokenNum = min(t.capacity, t.tokenNum+delta*t.rate)
astTime = now
判断是否有令牌
t.tokenNum > 0 {
.tokenNum--
return true
}
turn false
}
func min(a, b int) int {
a < b {
turn a
return b
}
func main() {
放行5个请求,最大突发容量10
imiter := NewTokenBucket(10, 5)
次并发请求
:= 0; i < 20; i++ {
f limiter.Allow() {
rintln("请求放行,当前序号:", i)
else {
intln("请求被限流,当前序号:", i)
time.Sleep(100 * time.Millisecond)
}
} } pr } p i for i// 模拟20 l // 每秒 }
re if re t if // t.l t. d no / t.mu } las mu las r cap "t "sy
三、代码运行结果与逻辑讲解
运行结果:前10个请求直接放行(突发流量支持),后续每秒固定放行5个请求,多余请求直接拦截,完美贴合线上接口限流需求。
核心原理拆解:
- 通过时间差自动补充令牌,无需单独开协程定时生成令牌,降低性能开销
- 加入sync.Mutex互斥锁,保证高并发场景下令牌计数线程安全
- 令牌数量不会超过桶最大容量,避免流量无限堆积
四、如何快速接入Gin Web框架?
只需要写一个全局中间件,所有接口统一限流,无需逐个接口改造:
func LimiterMiddleware(bucket *TokenBucket) gin.HandlerFunc {
urn func(c *gin.Context) {
f !bucket.Allow() {
(429,gin.H{"code":429,"msg":"请求过于频繁,请稍后再试"})
bort()
urn
t()
} }
c.Nex }
ret c.A c.JSON i ret
五、单机限流和分布式限流如何选型?
- 单机部署服务:直接使用本文原生令牌桶,零依赖、高性能、无网络开销
- 多节点分布式服务:基于Redis+Lua脚本实现分布式限流,保证全集群流量统一管控
六、面试高频问答总结
- 问:令牌桶和漏桶区别?答:令牌桶允许突发流量,漏桶严格限制流量速率
- 问:为什么不用定时协程生成令牌?答:时间差计算方式更节省goroutine资源,性能更高
- 问:高并发下如何保证计数安全?答:加互斥锁或者使用atomic原子操作
结语
限流不是复杂的中间件堆砌,合适的场景选择极简方案才是最优解。这段Go限流器代码可以直接复制用于个人项目和面试手撕代码,简单好用。需要分布式Redis限流完整版代码的小伙伴,关注后私信我免费领取。
觉得干货有用可以一键三连,后续持续更新Go云原生面试手撕代码合集。
更多推荐
所有评论(0)