新闻中心
Golang如何实现RESTful API限流
使用Golang实现RESTful API限流,核心是通过rate.Limiter结合中间件对不同客户端进行差异化控制。1. 利用golang.org/x/time/rate包实现令牌桶算法,支持突发流量与固定速率;2. 通过sync.RWMutex和map为每个IP或用户维护独立限流器,避免并发冲突;3. 在HTTP中间件中提取客户端标识并执行限流判断;4. 单机场景可用内存存储,分布式场景推荐uber-go/ratelimit或gorilla/throttled配合Redis实现滑动窗口限流。方案选择应根据系统规模权衡复杂度与性能需求。

在构建高并发的 RESTful API 服务时,限流是保障系统稳定性的重要手段。Golang 凭借其高效的并发模型和丰富的标准库,非常适合实现轻量且高效的限流机制。下面介绍几种常见的 Golang 实现方式。
使用令牌桶算法进行限流
令牌桶算法是一种经典且灵活的限流策略,允许一定程度的突发流量,同时控制平均速率。
Go 的 golang.org/x/time/rate 包提供了基于令牌桶的限流实现(rate.Limiter),非常适用于 HTTP 接口限流。
示例代码:
package main
import (
&q
uot;golang.org/x/time/rate"
"net/http"
"time"
)
var limiter = rate.NewLimiter(1, 5) // 每秒产生1个令牌,最多容纳5个令牌(支持突发)
func rateLimitedHandler(w http.ResponseWriter, r *http.Request) {
if !limiter.Allow() {
http.Error(w, "Too Many Requests", http.StatusTooManyRequests)
return
}
w.Write([]byte("Hello, Rate Limited World!"))
}
func main() {
http.HandleFunc("/api/hello", rateLimitedHandler)
http.ListenAndServe(":8080", nil)
}
上面的例子限制每秒最多处理1个请求,但允许最多5个请求的突发。
为不同用户或IP实现独立限流
实际应用中,通常需要对不同的客户端(如用户ID、IP地址)分别限流。
可以结合 map 和 sync.RWMutex 来管理多个限流器。
Musho
AI网页设计Figma插件
76
查看详情
示例:
type IPBasedLimiter struct {
limiters map[string]*rate.Limiter
mu sync.RWMutex
r rate.Limit
b int
}
func NewIPBasedLimiter(r rate.Limit, b int) *IPBasedLimiter {
return &IPBasedLimiter{
limiters: make(map[string]*rate.Limiter),
r: r,
b: b,
}
}
func (i *IPBasedLimiter) GetLimiter(ip string) *rate.Limiter {
i.mu.RLock()
limiter, exists := i.limiters[ip]
i.mu.RUnlock()
if !exists {
i.mu.Lock()
// 再次检查,避免重复创建
if _, found := i.limiters[ip]; !found {
i.limiters[ip] = rate.NewLimiter(i.r, i.b)
}
i.mu.Unlock()
}
return i.limiters[ip]
}
然后在中间件中使用:
func limitMiddleware(limiter *IPBasedLimiter) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ip := r.RemoteAddr // 实际使用中建议从 X-Forwarded-For 或其他头中提取真实IP
if !limiter.GetLimiter(ip).Allow() {
http.Error(w, "Rate limit exceeded", http.StatusTooManyRequests)
return
}
next.ServeHTTP(w, r)
})
}
}
使用第三方库简化实现
如果需要更复杂的功能(如持久化、分布式限流),可以考虑使用成熟库:
- uber-go/ratelimit:提供高精度的限流器。
- gorilla/throttled:支持存储后端(如内存、Redis),适合分布式场景。
- redis + lua 脚本:在分布式系统中,结合 Redis 实现滑动窗口限流。
例如,使用 throttled 实现每分钟最多10次请求:
store := memstore.New(65536)
quota := throttled.RateQuota{throttled.PerMin(10), 3}
rateLimiter, _ := throttled.NewGCRARateLimiter(store, quota)
httpRateLimiter := throttled.HTTPRateLimiter{
RateLimiter: rateLimiter,
VaryBy: &throttled.VaryBy{RemoteAddr: true},
}
// 使用 rateLimiter.Max(...))
小结
Go 实现 RESTful API 限流的核心思路是:利用 rate.Limiter 控制请求频率,通过中间件拦截请求,结合客户端标识(如 IP)做差异化限流。对于单机服务,标准库已足够;若需跨节点一致限流,建议引入 Redis 等共享存储。
基本上就这些,关键在于根据业务规模选择合适方案,避免过度设计。
以上就是Golang如何实现RESTful API限流的详细内容,更多请关注其它相关文章!
# 差异化
# 主动推广微信营销方案
# 咸宁市简述网站建设
# 丽佳美苑网站建设
# 小程序网站推广开发
# 步步高网站建设美丽
# 岳阳图文营销推广怎么做
# 网站搭建互联网推广
# js对SEO影响多大
# 山西网站优化好不好学
# 广州seo网站推广平台
# 如何在
# 多个
# 是一种
# redis
# 用户登录
# 客户端
# 最多
# 令牌
# 如何实现
# red
# 标准库
# restful api
# ai
# 后端
# golang
# go
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
台积电1.4nm工艺A14瞄准2028:10年来性能提升80%
QQ邮箱网页版入口 QQ邮箱官方邮箱登录通道
sublime如何配置Go语言开发环境_sublime搭建Golang编译运行系统
快手官方唯一登录入口 谨防山寨钓鱼网站
J*aScript中针对特定容器内图片动画的实现教程
Win10怎么设置静态IP地址 Win10手动配置IP地址步骤【指南】
Go语言中JSON数据解码与字段访问指南
如何在CSS中使用浮动制作导航栏_float实现水平菜单
AO3官方在线访问地址 Archive of Our Own最新镜像合集
CSS Box Model与弹性按钮:维持布局稳定的动画实践
使用CSS更改登录屏幕输入框中PNG图标颜色的策略与局限性
c++如何实现单例设计模式_c++线程安全的单例模式写法
零跑汽车11月交付量达70327台 实现连续9个月正增长
铁路12306改签能改到更早的车次吗_铁路12306改签提前车次规则
J*aScript生成器_j*ascript异步迭代
AO3官方镜像站点汇总 AO3同人作品网页版直达链接
12306怎么选座位选到安静区_12306选座安静区域选择策略
DLsite中文平台入口 DLsite官网内容在线查看
Basecamp怎样用留言钉固定重点_Basecamp用留言钉固定重点【重点标记】
React中useState与局部变量:理解组件状态管理与渲染机制
Go语言中动态执行代码字符串的策略与实践
Python大型XML文件高效流式解析教程
一加手机拍照效果不好怎么办 一加哈苏影像调校与专业模式使用教程【高手篇】
Node.js CSV 数据处理:基于字段空值条件过滤整条记录的策略
Python:递归比较文件夹内容并找出特定类型文件的差异
抖音从哪里进入网页版_抖音官方入口链接
Win11怎么关闭触摸屏_Windows 11禁用HID符合标准触摸屏
PHP中SSG-WSG API的AES加密实践:正确使用初始化向量
CSS实现侧边栏导航项全宽圆角悬停背景效果
Lar*el如何正确地在控制器和模型之间分配逻辑_Lar*el代码职责分离与架构建议
12306选座系统怎么选连座_12306选座多人连坐操作方法
J*a递归快速排序中静态变量的状态管理与陷阱
ACG动漫视频网入口 ACG动漫*免费正版观看地址
Linux如何构建多环境配置管理_Linux多环境配置方案
谷歌浏览器无痕模式怎么开 Chrome开启无痕浏览设置方法【教程】
Tailwind CSS line-clamp 布局问题解析与修复指南
Django表单提交验证失败后保持字段值不刷新
一加手机电池耗电快怎么办_一加手机电池耗电快的解决方法
J*a TimerTask文件监控:HashMap状态管理与常见陷阱规避指南
妖精漫画网页版登录入口免费_妖精漫画官网主页直接阅读漫画
J*aScript中localStorage数据的获取、清洗与格式化教程
C++如何检测键盘输入_C++ _kbhit与_getch函数非阻塞输入
Golang如何使用const iota_Go iota常量计数器讲解
J*a里如何实现订单支付与库存同步功能_支付库存同步项目开发方法说明
夸克浏览器桌面版同步不了书签怎么处理 夸克浏览器跨设备同步异常解决方案
NVIDIA股价11月重挫12%:下月有望好转 但难回5万亿美元巅峰
J*aScript教程:根据元素文本内容动态设置背景色
sublime怎么覆盖插件的默认快捷键_sublime快捷键优先级与设置
Eclipse怎么运行工程_Eclipse工程运行配置说明
css滚动动画效果怎么实现_使用Animate.css滚动触发动画类


2025-10-31
浏览次数:次
返回列表
uot;golang.org/x/time/rate"
"net/http"
"time"
)
var limiter = rate.NewLimiter(1, 5) // 每秒产生1个令牌,最多容纳5个令牌(支持突发)
func rateLimitedHandler(w http.ResponseWriter, r *http.Request) {
if !limiter.Allow() {
http.Error(w, "Too Many Requests", http.StatusTooManyRequests)
return
}
w.Write([]byte("Hello, Rate Limited World!"))
}
func main() {
http.HandleFunc("/api/hello", rateLimitedHandler)
http.ListenAndServe(":8080", nil)
}