Golang怎么实现IP限流_Golang如何按IP地址限制每个客户端的请求频率【实战】
用 golang.org/x/time/rate 实现 IP 限流需为每个 IP 绑定独立 rate.Limiter如存于 sync.Map合理设置 Every 和 burst定期清理闲置 IPHTTP 中间件须按可信代理网段解析真实客户端 IP避免伪造高并发时可哈希分片 sync.Map 或改用 Redis。用 golang.org/x/time/rate 做 IP 级限流最直接标准库没有内置 IP 限流但 rate.Limiter 是唯一靠谱的底层组件——它轻量、无锁、精度可控且不依赖外部存储。别碰 time.Sleep 手搓计数器也别一上来就上 Redis90% 的场景用它就够了。关键不是“能不能做”而是“怎么把 IP 和 Limiter 绑定住”。常见错误是全局只用一个 Limiter结果所有 IP 共享额度或者为每个新 IP 频繁新建 Limiter 却不回收导致内存缓慢上涨。每个 IP 对应一个独立的 rate.Limiter 实例比如存在 sync.Map 中用 rate.Every(1 * time.Second) 表示“每秒最多 N 次”比 rate.Limit(N) 更直观设置合理的 burst比如 5避免网络抖动导致正常请求被误拒定期清理长时间未访问的 IP 条目例如 30 分钟无请求就 delete否则 sync.Map 会持续膨胀HTTP 中间件里怎么安全提取真实客户端 IP直接读 r.RemoteAddr 只能得到代理或负载均衡器的地址不是真实用户 IP。必须按顺序检查 X-Forwarded-For、X-Real-IP 等 header但不能全信——这些字段可被伪造。真正能信任的只有你自己的反向代理如 Nginx加的 header而且必须配置 set_real_ip_from real_ip_header。Golang 层要做的是只从可信 hop 列表里取最后一个非内网地址。立即学习“go语言免费学习笔记深入”硬编码可信代理网段如 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16其他来源的 X-Forwarded-For 一律忽略用 net.ParseIP net.Contains 判断是否为内网地址别用字符串匹配如果所有 header 都不可信fallback 到 r.RemoteAddr 的 IP 部分用 strings.Split(r.RemoteAddr, :)[0]注意 IPv6 地址格式r.RemoteAddr 可能带方括号需先 net.ParseIP 再格式化输出并发高时 sync.Map 性能不够怎么办sync.Map 在读多写少时表现好但每秒几千次写入比如大量新 IP 首次访问会导致 LoadOrStore 明显延迟。这不是 bug是设计取舍它不保证遍历一致性也不支持原子删除。 Tellers AI Tellers是一款自动视频编辑工具可以将文本、文章或故事转换为视频。