新闻中心
如何用Golang实现请求限流_Golang Web请求限流技巧
固定窗口计数限流存在临界突刺问题,适合低精度场景;令牌桶算法通过golang.org/x/time/rate实现平滑限流,支持突发流量;分布式环境下需结合Redis的INCR与EXPIRE命令或Lua脚本实现全局限流,确保多实例间请求控制一致。

在高并发场景下,控制请求频率是保护后端服务稳定的重要手段。Golang 因其高效的并发模型,非常适合实现请求限流。常见的限流策略有固定窗口、滑动窗口、漏桶和令牌桶算法。下面介绍几种实用的 Golang 请求限流技巧,帮助你在 Web 服务中有效控制流量。
使用标准库实现简单的计数器限流
最基础的限流方式是固定时间窗口计数。比如限制每秒最多 100 个请求,可以维护一个每秒重置的计数器。
虽然简单,但存在“临界突刺”问题——大量请求可能集中在窗口切换时通过。适合对精度要求不高的场景。
示例代码:
var (
requestCount int
lastReset = time.Now()
mu sync.Mutex
)
func rateLimitMiddleware(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
mu.Lock()
now := time.Now()
if now.Sub(lastReset) > time.Second {
requestCount = 0
lastReset = now
}
if requestCount >= 100 {
http.StatusTooManyRequests, nil)
return
}
requestCount++
mu.Unlock()
next(w, r)
}
}
基于 Token Bucket 的平滑限流
令牌桶算法允许突发流量,同时控制平均速率,是更灵活的选择。Golang 标准库 golang.org/x/time/rate 提供了开箱即用的实现。
你可以为每个客户端或全局创建一个限流器,控制每秒生成的令牌数和最大突发量。
常见用法:
- 每秒填充 10 个令牌,最多允许突发 50 个请求
- 使用 Allow() 或 Wait() 方法判断是否放行请求
- 结合 context 实现超时控制
import "golang.org/x/time/rate"
var limiter = rate.NewLimiter(10, 50) // 10rps, burst=50
func limitHandler(w http.ResponseWriter, r *http.Request) {
if !limiter.Allow() {
http.StatusTooManyRequests, nil)
return
}
// 处理业务逻辑
}
分布式环境下的限流方案
单机限流无法应对多实例部署。要实现全局限流,需依赖共享存储如 Redis。
利用 Redis 的 INCR 和 EXPIRE 命令,可实现分布式固定窗口限流。Lua 脚本
能保证原子性操作。
小云雀
剪映出品的AI视频和图片创作助手
1949
查看详情
推荐使用 RediSearch 或直接调用 Lua 脚本实现滑动窗口算法,避免多个命令间的竞争问题。
例如:统计最近一分钟的请求数,超过阈值则拒绝。
// Lua script example for sliding window
local count = redis.call("INCR", KEYS[1])
if count == 1 then
redis.call("EXPIRE", KEYS[1], 60)
end
return count <= tonumber(ARGV[1]) and 1 or 0
在 Go 中使用 go-redis 驱动执行该脚本,实现跨节点一致的限流控制。
中间件方式集成限流逻辑
将限流封装成 HTTP 中间件,便于复用和组合。可以根据路径、IP、用户 ID 等维度设置不同规则。
建议结构:
- 定义限流配置结构体,包含 qps、burst、keyFunc(如获取客户端 IP)
- 使用 map + sync.RWMutex 缓存每个 key 对应的限流器
- 定期清理长时间不用的限流器,防止内存泄漏
这样既能支持个性化限流,又能保持性能开销可控。
基本上就这些。选择合适的算法取决于你的业务需求:追求简单可用选 token bucket,需要精确控制用滑动窗口,分布式系统别忘了引入 Redis。合理限流,既能防刷又能保障核心服务稳定。
以上就是如何用Golang实现请求限流_Golang Web请求限流技巧的详细内容,更多请关注其它相关文章!
# 用户登录
# 采集站seo赚钱课程
# 推广营销活动主持稿
# seo是什么方向
# 传奇手游推广网站哪个好
# 昆明网站营销与推广加盟
# 营销推广广告策划案例
# 最优的赣州网站建设
# 关键词排名81超人8
# 营销策略和推广的区别
# 越秀区seo优化多少钱
# 多个
# 客户端
# 既能
# redis
# 又能
# 最多
# 如何用
# 令牌
# 如何实现
# red
# 标准库
# win
# ai
# 后端
# golang
# go
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
Bing引擎入口最新2025 Bing搜索免费官方登录
word中如何让数字纵向排列_Word数字纵向排列方法
cad怎么合并重叠的线段_cad清理重复重叠线条的操作方法
解决 Vaadin 8 中大文件音频播放与定位时出现的 IOException
QQ邮箱正确登录入口_QQ邮箱官方网站使用地址
动漫岛观看全网网 动漫岛在线正版动漫入口
知乎APP怎么管理已购盐选内容_知乎APP盐选内容购买记录与查看方法
我的世界官方游戏入口 我的世界官网平台直达链接
ArrayList与LinkedList操作复杂度详解:遍历与修改
精准捕获:如何在页面中监听除特定元素外的所有点击事件
Go语言JSON解析深度指南:动态访问与结构体映射实践
使用 Pandas 高效处理 .dat 文件:字符清理与数据计算
怎么在html里运行vbs脚本_html中运行vbs脚本方法【教程】
零跑汽车11月交付量达70327台 实现连续9个月正增长
照顾宝贝2小游戏点击立即在线玩
浏览器打开即用 美图秀秀网页版入口
如何使用CaptainHook和Composer管理Git钩子_在提交前自动运行代码检查的Composer配置
KFC套餐升级怎么获取优惠代码_KFC套餐升级活动与优惠代码获取方法
BetterDiscord插件中安全更新用户简介的实践指南
抓大鹅无需下载版 抓大鹅秒玩版入口
AO3最新官网入口公告_2025AO3镜像站实时查询方法
QQ邮箱登录平台入口 QQ邮箱网页版邮箱官方入口
C++20的source_location是什么_C++在编译期获取源码位置信息用于日志和断言
Go语言中Map存储的结构体如何调用指针方法:深入解析与实践
J*aScript动态修改指定div内所有a标签样式指南
C++ map遍历方法大全_C++ map迭代器使用总结
双系统安装时,如何设置默认启动系统? msconfig命令了解一下!
QQ邮箱在线使用入口 QQ邮箱个人账号网页版登录
解决Python logging 中 datefmt 导致时间戳固定不变的问题
如何解决电商平台定制报价请求的“黑洞”问题,SprykerQuoteRequest模块助你提升客户体验与销售效率
深入理解与实现最大堆的Heapify过程:常见错误与修正
J*a TimerTask文件监控:HashMap状态管理与常见陷阱规避指南
一加手机电池耗电快怎么办_一加手机电池耗电快的解决方法
C++如何进行游戏物理模拟_使用Box2D库为C++游戏添加2D物理效果
将HTML Canvas内容转换为可上传的图像文件(File对象)
J*a递归快速排序中静态变量导致数据累积的陷阱与解决方案
黑猫投诉统一入口官网 消费者权益保护投诉平台
Win10系统怎么查看已安装更新_Win10卸载有问题的更新补丁
《铁拳8》黑皮辣妹新实机:元气满满的18岁少女!
c++ 获取系统当前时间 c++时间戳获取方法
c++如何使用chrono库处理时间_c++标准库时间与日期操作
天眼查怎么看公司融资情况 天眼查企业融资历史查询步骤【攻略】
手机CPU怎么影响游戏体验_手机CPU对游戏性能的影响分析
J*aScript map 迭代中检测空数组元素的有效方法
将HTML动态表格多行数据保存到Google Sheet的教程
包子漫画官方网站阅读入口-包子漫画在线漫画官网直达链接
Win10如何开启蓝牙功能_Windows10找不到蓝牙开关解决方法
在J*a中如何使用Exception包装底层异常_异常包装与信息传递方法说明
C++如何实现一个智能指针_手动实现C++ shared_ptr的引用计数功能
QQ邮箱官方网站登录入口_QQ邮箱网页版在线使用


2025-11-19
浏览次数:次
返回列表