- 包子句 IPRateLimiter → ipratelimiter(符合 Go 小写命名惯例), 消费方 限定符同步; 新增依赖 golang.org/x/time - 附测试、examples/ipratelimiter 例程与包 README
38 lines
1.2 KiB
Markdown
38 lines
1.2 KiB
Markdown
# ipratelimiter
|
|
|
|
按 IP 维度管理的令牌桶限流器(基于 `golang.org/x/time/rate`):为每个 IP 维护
|
|
独立 `rate.Limiter`,典型用于 Gin 中间件按客户端 IP 限流。
|
|
|
|
> 迁移自 go-hua/ipratelimiter,并将包子句 `IPRateLimiter` 修正为 Go 惯例的
|
|
> 小写 `ipratelimiter`(原包名大写不符合 Go 命名规范)。
|
|
|
|
## 用法
|
|
|
|
```go
|
|
import (
|
|
"net/http"
|
|
|
|
"git.zeroonesoft.cn/golib/zogo/ipratelimiter"
|
|
"golang.org/x/time/rate"
|
|
)
|
|
|
|
// 每 IP 每秒 2 个请求,桶容量 3
|
|
limiterSet := ipratelimiter.NewIPRateLimiter(rate.Limit(2), 3)
|
|
|
|
func handler(w http.ResponseWriter, r *http.Request) {
|
|
lim := limiterSet.GetLimiter(r.RemoteAddr) // 不存在则自动 AddIP
|
|
if !lim.Allow() {
|
|
http.Error(w, "too many requests", http.StatusTooManyRequests)
|
|
return
|
|
}
|
|
// ...业务
|
|
}
|
|
```
|
|
|
|
完整可运行例程:[examples/ipratelimiter/main.go](../examples/ipratelimiter/main.go)
|
|
|
|
## 注意
|
|
|
|
- 内部 map 只增不减,海量公网 IP 场景需自行加过期清理(或前置 CDN/网关限流)。
|
|
- 限流参数与 `golang.org/x/time/rate` 语义一致:`rate.Limit` 为每秒令牌数,`b` 为桶容量。
|