
How to Rate Limit HTTP Requests
2.1 使用
2.4 使用
发布日期:2021-05-16 21:14:01
浏览次数:20
分类:精选文章
本文共 3602 字,大约阅读时间需要 12 分钟。
HTTP速率限制实现指南
1. 简单速率限制
在Go语言中,使用golang.org/x/time/rate
包可以轻松实现速率限制功能。这是一个功能强大、维护良好的库,适合处理各种速率限制场景。然而,如果你想要一个轻量级的解决方案,或者想自己实现,可以按照以下步骤操作:
1.1 安装所需依赖
首先,安装速率限制包:
go get golang.org/x/time/rate
1.2 创建项目结构
创建一个包含limit.go
和main.go
的目录:
mkdir ratelimit-democd ratelimit-demotouch limit.go main.go
1.3 实现速率限制中枢
在limit.go
文件中定义速率限制器:
package mainimport ( "net/http" "golang.org/x/time/rate")var limiter = rate.NewLimiter(2, 5)func limit(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if limiter.Allow() == false { http.Error(w, http.StatusText(429), http.StatusTooManyRequests) return } next.ServeHTTP(w, r) })}
1.4 整合速率限制到服务器
在main.go
文件中,使用limit
中枢包装路由:
package mainimport ( "net/http")func main() { mux := http.NewServeMux() mux.HandleFunc("/", okHandler) http.ListenAndServe(":4000", limit(mux))}func okHandler(w http.ResponseWriter, r *http.Request) { w.Write([]byte("OK"))}
1.5 测试速率限制
运行应用并使用curl发送请求观察结果:
go run *.gocurl -i localhost:4000
1.6 处理用户速率
如果需要按用户(如IP地址)进行速率限制,可以在limit.go
中扩展实现。以下是实现细节:
package mainimport ( "net/http" "sync" "golang.org/x/time/rate")var visitors = make(map[string]*rate.Limiter)var mtx sync.Mutex// 添加用户速率限制func addVisitor(ip string) *rate.Limiter { limiter := rate.NewLimiter(2, 5) mtx.Lock() visitors[ip] = limiter mtx.Unlock() return limiter}// 获取或创建用户速率限制func getVisitor(ip string) *rate.Limiter { mtx.Lock() limiter, exists := visitors[ip] if !exists { mtx.Unlock() return addVisitor(ip) } mtx.Unlock() return limiter}// 更新用户最后访问时间// 同时清除过期访问记录func limit(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { limiter := getVisitor(r.RemoteAddr) if limiter.Allow() == false { http.Error(w, http.StatusText(429), http.StatusTooManyRequests) return } next.ServeHTTP(w, r) })}
2. 清理过期访问
为了避免内存泄漏,可以在后台执行清理任务:
package mainimport ( "net/http" "sync" "time" "golang.org/x/time/rate")type visitor struct { limiter *rate.Limiter lastSeen time.Time}var visitors = make(map[string]*visitor)var mtx sync.Mutex// 初始化清理任务func init() { go cleanupVisitors()}// 清理定时任务func cleanupVisitors() { for { time.Sleep(time.Minute) mtx.Lock() for ip, v := range visitors { if time.Now().Sub(v.lastSeen) > 3*time.Minute { delete(visitors, ip) } } mtx.Unlock() }}// 添加新访客func addVisitor(ip string) *rate.Limiter { limiter := rate.NewLimiter(2, 5) mtx.Lock() visitors[ip] = &visitor{limiter: limiter, lastSeen: time.Now()} mtx.Unlock() return limiter}// 获取或创建访客速率限制func getVisitor(ip string) *rate.Limiter { mtx.Lock() v, exists := visitors[ip] if !exists { mtx.Unlock() return addVisitor(ip) } v.lastSeen = time.Now() mtx.Unlock() return v.limiter}// 应用速率限制中枢func limit(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { limiter := getVisitor(r.RemoteAddr) if limiter.Allow() == false { http.Error(w, http.StatusText(429), http.StatusTooManyRequests) return } next.ServeHTTP(w, r) })}
2. 性能优化建议
2.1 使用sync.RWMutex
代替sync.Mutex
以降低 contention。
2.2 根据实际需求定制化配置参数。
2.3 考虑将速率限制器包装为可配置模块,以支持不同的资源和策略。
2.4 使用VulnChecker
进行性能测试,确保系统在高负载下稳定运行。
3. 总结
通过以上方法,你可以轻松实现HTTP服务器的速率限制功能。无论是全局速率限制,还是按用户(如IP地址)定制速率限制,都可以根据实际需求选择合适的实现方案。Go语言的优雅语法和高效的标准库,使得实现和迭代依然非常简单和高效。
发表评论
最新留言
第一次来,支持一个
[***.219.124.196]2025年04月26日 16时35分30秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
java书籍_还搞不定Java多线程和并发编程面试题?你可能需要这一份书单!
2023-01-24
java序列化_java对象的序列化和反序列化
2023-01-24
java开发区块链_用Java代码实现区块链
2023-01-24
java快捷键eclipse_eclipse的设置和一些快捷键
2023-01-24
java拼车平台(ssm框架毕业设计)
2023-01-24
Java指定区间返回随机数
2023-01-24
Java推动老年人社区服务(毕设源码+mysql+lw)
2023-01-24
Java提高班(六)反射和动态代理(JDK Proxy和Cglib)
2023-01-24
java操作List
2023-01-24
Java操作Sql语句 出现迭代死循环 (Bug排查)
2023-01-24
#Leetcode# 92. Reverse Linked List II
2023-01-24
java攀枝花市房屋租售信息管理平台的设计与实现(ssm)
2023-01-24
java教学团队管理系统(ssm)
2023-01-24
java教学网站(ssm)
2023-01-24
java教学质量管理平台(ssm)
2023-01-24
java教师信息采集系统(ssm)
2023-01-24
java教师教学质量评估系统(ssm)
2023-01-24
java教师管理系统(ssm)
2023-01-24
java教师管理系统(ssm)
2023-01-24