V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
mantis
V2EX  ›  Go 编程语言

基于 Go 语言设计的一款高精度 QPS 统计系统,适用于高并发场景的实时请求频率统计,支持百万级 QPS 场景下的精确统计。

  •  
  •   mantis · 18 小时 38 分钟前 · 868 次点击

    高精度 QPS 统计系统,适用于高并发场景的实时请求频率统计。基于 Go 语言实现的高性能计数器,支持百万级 QPS 场景下的精确统计。

    Github

    ✨ 核心特性

    • 🚀 双引擎架构( Lock-Free/Sharded ),支持百万级 QPS 实时统计
    • 🔄 智能分片策略(基于 CPU 核心数的动态分片,10 秒间隔 QPS 监控)
    • ⚡ 时间窗口滑动算法( 1s 窗口,100ms 精度)
    • 🧠 自适应负载均衡( QPS 变化率超 30%自动调整)
    • 🛡️ 增强的优雅关闭机制(请求完整性保障,超时控制,强制关闭)
    • 🔒 令牌桶限流保护(可动态调整速率,支持突发流量,自适应限流)
    • 📊 Prometheus 监控集成( QPS 、内存、CPU 、请求延迟等指标)
    • ✅ 健康检查端点支持(/healthz )
    • 📈 资源使用监控指标(内存阈值自适应,自动分片调整)
    • ⚙️ 高性能设计(原子操作、细粒度锁、请求计数与统计)
    • 🌐 HTTP 服务器双模式支持(标准 net/http 和高性能 fasthttp )

    🏗 架构设计

    +-------------------+     +-----------------------+
    |   HTTP Server     | ⇒  |  Adaptive Sharding    |
    | (net/http,fasthttp)|    +-----------------------+
    +-------------------+     
          ↓                               ↓
    +---------------+        +------------------------+
    | Lock-Free 引擎 |        | Sharded 计数器集群       |
    | (CAS 原子操作)  |        | (动态分片)              |
    +---------------+        +------------------------+
                                    ⇓
    +------------------------------------------------+
    |           动态分片管理器                       |
    |  • 10 秒间隔监控 QPS 变化率(±30%触发调整)        |
    |  • 分片数自动伸缩(最小 CPU 核心数,最大 CPU 核心数*8 )|
    |  • 内存使用监控(自动调整分片以优化内存使用)     |
    +------------------------------------------------+
                                    ⇓
    +------------------+  +------------------+  +------------------+
    |    限流保护层    |  |    监控指标层    |  |   优雅关闭机制   |
    | (令牌桶+自适应)  |  | (Prometheus 集成) |  | (请求完整性保障) |
    +------------------+  +------------------+  +------------------+
    

    🔍 技术实现

    Lock-Free 引擎

    基于原子操作( CAS )实现的无锁计数器,适用于中等流量场景:

    • 使用atomic.Int64实现无锁计数,避免高并发下的锁竞争
    • 时间窗口滑动算法,保证统计精度和实时性
    • 自动清理过期数据,避免内存泄漏

    Sharded 计数器

    分片设计的高性能计数器,适用于超高并发场景:

    • 基于 CPU 核心数的自动分片,默认为runtime.NumCPU() * 4
    • 细粒度锁设计,每个时间槽独立锁,最大化并行性
    • 哈希算法确保请求均匀分布到各分片

    自适应分片管理

    • 实时监控 QPS 变化率,当变化超过±30%时触发分片调整
    • 增长时增加 50%分片数,下降时减少 30%分片数
    • 分片数范围控制在 CPU 核心数到 CPU 核心数*8 之间,避免资源浪费
    • 内存使用监控,当接近阈值时自动调整分片数量
    • 综合考量 QPS 变化率(60%)和内存使用情况(40%)进行智能调整

    令牌桶限流器

    • 基于令牌桶算法实现高效限流,支持突发流量处理
    • 动态调整限流速率,适应系统负载变化
    • 自适应限流模式,根据系统资源使用情况自动调整限流参数
    • 精确统计被拒绝请求,提供限流指标监控

    监控指标系统

    • 集成 Prometheus ,提供丰富的系统运行指标
    • 实时监控 QPS 、内存使用、CPU 使用率、Goroutine 数量
    • 请求延迟分布统计,支持 P99 等性能分析
    • 可配置的指标收集间隔,优化性能与精度平衡

    增强的优雅关闭机制

    • 请求完整性保障,确保进行中的请求能够完成处理
    • 多级超时控制,包括软超时和硬超时机制
    • 实时状态报告,提供关闭过程的可观测性
    • 强制关闭保护,防止系统长时间无法退出

    ⚙️ 配置说明

    server:
      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: 请求处理时间分布

    🛠 开发指南

    环境要求

    • Go 1.18+
    • Make

    本地开发

    1. 克隆仓库
    git clone https://github.com/mant7s/qps-counter.git
    cd qps-counter
    
    1. 安装依赖
    go mod download
    
    1. 运行测试
    make test
    
    1. 构建项目
    make build
    
    3 条回复    2025-03-16 14:50:32 +08:00
    faceair
        1
    faceair  
       18 小时 1 分钟前 via iPhone
    没看懂,直接用 prometheus sdk 有啥问题
    lesismal
        2
    lesismal  
       14 小时 15 分钟前
    atomic.AddUint64 1ns 级别的,1s 百万也没什么压力的,shards slots 的计算量比简单 atomic 浪费的 cpu 多多了,我觉得是多余的设计。
    如果需要保存一段时间内数据、就用 len=时长/interval ,[len]uint64 ,起个协程每个 interval 更新下 index=(index+1)%numSlots ,qps 的地方 atomic.AddUint64(&slots[index], 1)就可以了,没必要搞那么多有锁无锁的炫技,脱离实际的炫技会带来负优化
    zzhirong
        3
    zzhirong  
       13 小时 28 分钟前   ❤️ 4
    项目有很浓的 AI 味,我花了半小时看了下,有几个疑问:
    – 自适应分区究竟有什么用?我只看到分区调整,好像并未真正应用;
    – 自适应限流似乎并未实现,只见一个 adaptive 字段,却看不到任何实际使用;
    – 这个项目的意义何在?仅仅是统计 QPS 吗?(既然都用 Prometheus ,为何不直接上报,而要绕一个弯路)或者是作为中心限流器?(我的理解这个一般在流量入口(负载均衡或网关)处就做掉了吧) 。
    – 令牌桶已有 golang.org/x/time/rate 这样稳定的实现了,没必要再造轮子了吧。
    总结:一个项目把所有后端爆款关键字都用上了(“百万”,“精确”,“高性能”,“优雅”,“自适应”,“智能”...),我的感觉就是一个( AI )炼手的项目。
    唉,我的时间。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   868 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 18ms · UTC 20:19 · PVG 04:19 · LAX 13:19 · JFK 16:19
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.