feat(ipratelimiter): 自 go-hua 迁入按 IP 令牌桶限流器并修正包子句
- 包子句 IPRateLimiter → ipratelimiter(符合 Go 小写命名惯例), 消费方 限定符同步; 新增依赖 golang.org/x/time - 附测试、examples/ipratelimiter 例程与包 README
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
# 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` 为桶容量。
|
||||
Reference in New Issue
Block a user