首页 > 后端开发 > Golang > 正文

Golang HTTP请求限流与并发控制项目

P粉602998670
发布: 2025-10-10 17:00:01
原创
432人浏览过
使用令牌桶和信号量机制控制限流与并发,保障Golang HTTP服务稳定性。首先通过golang.org/x/time/rate实现每秒10个请求、突发50的令牌桶限流;接着用带缓冲channel(容量5)限制最大并发数,防止资源耗尽;最后结合IP级限流管理器,按IP维度分配独立令牌桶,并定期清理长时间未活跃的IP记录,实现精细化控制。实际应用中建议结合监控动态调整阈值。

golang http请求限流与并发控制项目

在构建高并发的 Golang HTTP 服务时,控制请求频率和并发量是保障系统稳定的关键。不加限制的请求可能导致后端资源耗尽、响应延迟上升甚至服务崩溃。通过合理的限流与并发控制机制,可以有效保护服务稳定性,提升用户体验。

使用令牌桶实现HTTP请求限流

令牌桶算法是一种常见且灵活的限流方式,它允许一定程度的突发流量,同时保证平均速率不超过设定值。Golang 标准库 golang.org/x/time/rate 提供了开箱即用的令牌桶实现。

以下是一个基于 rate.Limiter 的中间件示例:

package main
<p>import (
"golang.org/x/time/rate"
"net/http"
"time"
)</p><p>var limiter = rate.NewLimiter(10, 50) // 每秒10个令牌,最多容纳50个</p><p><span>立即学习</span>“<a href="https://pan.quark.cn/s/00968c3c2c15" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">go语言免费学习笔记(深入)</a>”;</p><p>func rateLimit(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if !limiter.Allow() {
http.StatusText(http.StatusTooManyRequests)
http.Error(w, "请求过于频繁", http.StatusTooManyRequests)
return
}
next.ServeHTTP(w, r)
}
}</p><p>func handler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("处理请求"))
}</p><p>func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", rateLimit(handler))
http.ListenAndServe(":8080", mux)
}
登录后复制

上面代码中,每秒最多处理10个请求,最多可积压40个(burst=50)。适合用于API接口防刷或防止爬虫滥用。

控制最大并发请求

除了按时间频率限流,有时需要硬性限制同时处理的请求数量,防止资源(如数据库连接、内存)被耗尽。可以通过带缓冲的 channel 实现信号量机制。

示例:限制最多同时处理5个请求

PatentPal专利申请写作
PatentPal专利申请写作

AI软件来为专利申请自动生成内容

PatentPal专利申请写作 13
查看详情 PatentPal专利申请写作
var sem = make(chan struct{}, 5)
<p>func concurrencyLimit(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
select {
case sem <- struct{}{}:
// 获取执行权
default:
http.Error(w, "服务繁忙,请稍后再试", http.StatusServiceUnavailable)
return
}
defer func() { <-sem }() // 释放
next.ServeHTTP(w, r)
}
}
登录后复制

该方法简单有效,适用于 IO 密集型任务较多、资源敏感的服务场景。

结合限流与并发控制的完整结构

实际项目中,通常将两种策略结合使用。例如:先通过并发控制防止系统过载,再用限流器平滑请求分布。

可以封装一个通用的限流管理器,支持按 IP 或用户维度进行控制:

type IpLimiter struct {
    mu sync.RWMutex
    limiters map[string]*rate.Limiter
    lastSeen map[string]time.Time
    r  float64
    b int
}
<p>func NewIpLimiter(r float64, b int) <em>IpLimiter {
il := &IpLimiter{
limiters: make(map[string]</em>rate.Limiter),
lastSeen: make(map[string]time.Time),
r: r,
b: b,
}
go il.cleanup()
return il
}</p><p>func (il <em>IpLimiter) GetLimiter(ip string) </em>rate.Limiter {
il.mu.Lock()
defer il.mu.Unlock()</p><pre class="brush:php;toolbar:false;"><pre class="brush:php;toolbar:false;">limiter, exists := il.limiters[ip]
if !exists {
    limiter = rate.NewLimiter(il.r, il.b)
    il.limiters[ip] = limiter
    il.lastSeen[ip] = time.Now()
} else {
    il.lastSeen[ip] = time.Now()
}
return limiter
登录后复制

}

func (il IpLimiter) cleanup() { for { time.Sleep(time.Minute) il.mu.Lock() for ip, last := range il.lastSeen { if time.Since(last) > 3time.Minute { delete(il.limiters, ip) delete(il.lastSeen, ip) } } il.mu.Unlock() } }

在中间件中调用:

var ipLimiter = NewIpLimiter(1, 5) // 每秒1次,最多5次突发
<p>func limitByIP(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
ip := r.RemoteAddr
if !ipLimiter.GetLimiter(ip).Allow() {
http.Error(w, "访问过于频繁", http.StatusTooManyRequests)
return
}
next(w, r)
}
}
登录后复制

基本上就这些。通过合理组合令牌桶限流与 channel 控制并发,可以构建出稳定可靠的 HTTP 服务。关键是根据业务场景选择合适的阈值,并配合监控及时调整策略。

以上就是Golang HTTP请求限流与并发控制项目的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号