
高精度 QPS 统计系统,适用于高并发场景的实时请求频率统计。基于 Go 语言实现的高性能计数器,支持百万级 QPS 场景下的精确统计。
+-------------------+ +-----------------------+ | HTTP Server | | Adaptive Sharding | | (net/http,fasthttp)| +-----------------------+ +-------------------+ ↓ ↓ +---------------+ +------------------------+ | Lock-Free 引擎 | | Sharded 计数器集群 | | (CAS 原子操作) | | (动态分片) | +---------------+ +------------------------+ +------------------------------------------------+ | 动态分片管理器 | | 10 秒间隔监控 QPS 变化率(±30%触发调整) | | 分片数自动伸缩(最小 CPU 核心数,最大 CPU 核心数*8 )| | 内存使用监控(自动调整分片以优化内存使用) | +------------------------------------------------+ +------------------+ +------------------+ +------------------+ | 限流保护层 | | 监控指标层 | | 优雅关闭机制 | | (令牌桶+自适应) | | (Prometheus 集成) | | (请求完整性保障) | +------------------+ +------------------+ +------------------+ 基于原子操作( CAS )实现的无锁计数器,适用于中等流量场景:
atomic.Int64实现无锁计数,避免高并发下的锁竞争分片设计的高性能计数器,适用于超高并发场景:
runtime.NumCPU() * 4server: port: 8080 read_timeout: 5s write_timeout: 10s server_type: fasthttp # HTTP 服务器类型( standard/fasthttp ) counter: type: "lockfree" # 计数器类型( lockfree/sharded ) window_size: 1s # 统计时间窗口 slot_num: 10 # 窗口分片数量 precision: 100ms # 统计精度 limiter: enabled: true # 是否启用限流 rate: 1000000 # 每秒允许的请求数 burst: 10000 # 突发请求容量 adaptive: true # 是否启用自适应限流 metrics: enabled: true # 是否启用指标收集 interval: 5s # 指标收集间隔 endpoint: "/metrics" # 指标暴露端点 shutdown: timeout: 30s # 优雅关闭超时时间 max_wait: 60s # 最大等待时间 logger: level: info format: json file_path: "/var/log/qps-counter/app.log" max_size: 100 max_backups: 3 max_age: 7 | 服务器类型 | 并发量 | 平均延迟 | P99 延迟 | QPS |
|---|---|---|---|---|
| standard | 10k | 1.8ms | 4.5ms | 850k |
| fasthttp | 10k | 1.2ms | 3.5ms | 950k |
高负载场景测试结果: | 服务器类型 | 并发量 | 平均延迟 | P99 延迟 | QPS | |------------|--------|---------|--------|--------| | standard | 100k | 2.5ms | 6.5ms | 1.05M | | fasthttp | 100k | 1.2ms | 3.5ms | 1.23M |
go get github.com/mant7s/qps-counter package main import ( "github.com/mant7s/qps-counter/counter" "log" ) func main() { // 创建计数器实例 cfg := counter.DefaultConfig() counter, err := counter.NewCounter(cfg) if err != nil { log.Fatal(err) } // 增加计数 counter.Increment() // 获取当前 QPS qps := counter.GetQPS() log.Printf("Current QPS: %d", qps) } 系统通过/metrics端点暴露 Prometheus 格式的监控指标:
qps_counter_requests_total: 总请求计数qps_counter_current_qps: 当前 QPS 值qps_counter_memory_usage_bytes: 内存使用量qps_counter_cpu_usage_percent: CPU 使用率qps_counter_goroutines: Goroutine 数量qps_counter_request_duration_seconds: 请求处理时间分布git clone https://github.com/mant7s/qps-counter.git cd qps-counter go mod download make test make build 1 faceair 278 天前 via iPhone 没看懂,直接用 prometheus sdk 有啥问题 |
2 lesismal 278 天前 atomic.AddUint64 1ns 级别的,1s 百万也没什么压力的,shards slots 的计算量比简单 atomic 浪费的 cpu 多多了,我觉得是多余的设计。 如果需要保存一段时间内数据、就用 len=时长/interval ,[len]uint64 ,起个协程每个 interval 更新下 index=(index+1)%numSlots ,qps 的地方 atomic.AddUint64(&slots[index], 1)就可以了,没必要搞那么多有锁无锁的炫技,脱离实际的炫技会带来负优化 |
3 zzhirong 278 天前 项目有很浓的 AI 味,我花了半小时看了下,有几个疑问: 自适应分区究竟有什么用?我只看到分区调整,好像并未真正应用; 自适应限流似乎并未实现,只见一个 adaptive 字段,却看不到任何实际使用; 这个项目的意义何在?仅仅是统计 QPS 吗?(既然都用 Prometheus ,为何不直接上报,而要绕一个弯路)或者是作为中心限流器?(我的理解这个一般在流量入口(负载均衡或网关)处就做掉了吧) 。 令牌桶已有 golang.org/x/time/rate 这样稳定的实现了,没必要再造轮子了吧。 总结:一个项目把所有后端爆款关键字都用上了(“百万”,“精确”,“高性能”,“优雅”,“自适应”,“智能”...),我的感觉就是一个( AI )炼手的项目。 唉,我的时间。 |