Fork me on GitHub

版权声明 本站原创文章 由 萌叔 发表
转载请注明 萌叔 | https://vearne.cc

引言

我们打算统计服务的QPS,原型已经选了
go-metrics
PS: 1800多个star看来不会错
但是我还是打算自己实现一版,看看我自己的实现和它的实现有什么不同

实现

package main

import (
    "fmt"
    "time"
)

type MeterRate1 struct {
    count int64
    // start和end 是一段移动的时间区间
    // start和end 都是自新纪元起经历的秒数
    // end - start = 60 seconds
    start int64
    end   int64
    // 存储某一时刻,对应的count值
    timestampCountMap map[int64]int64
}

func NewMeterRate1() *MeterRate1 {
    m := MeterRate1{}
    m.count = 0
    t := time.Now().Unix()
    m.start = t - 60
    m.end = t
    m.timestampCountMap = make(map[int64]int64, 60)

    // 启动一个协程用于每秒"快照"
    go MeterTick(&m)
    return &m
}

func (m *MeterRate1) Mark(n int64) {
    m.count += n
}

func (m *MeterRate1) Rate() float64 {
    return float64(m.timestampCountMap[m.end]-m.timestampCountMap[m.start]) / 60.0
}

func MeterTick(m *MeterRate1) {
    // 每秒触发一次, 快照这一时刻的count值, 存入timestampCountMap
    c := time.Tick(time.Second * 1)
    for x := range c {
        fmt.Println("tick", x)
        t := time.Now().Unix()
        m.timestampCountMap[t] = m.count
        m.start = t - 60
        m.end = t
        delete(m.timestampCountMap, m.start-1)
        fmt.Println("---------------")
        for i := m.start; i < m.end+1; i++ {
            fmt.Printf("time:%v, count:%v\n", i, m.timestampCountMap[i])
        }
    }
}

func main() {
    m := NewMeterRate1()
    go MyPrint2(m)
    var j int64 = 1
    for true {
        time.Sleep(time.Second * 1)
        j++
        m.Mark(j)
    }
}

func MyPrint2(m *MeterRate1) {
    for true {
        time.Sleep(time.Second)
        fmt.Println("rate1", m.Rate())
    }
}

在下一篇文章中,我会来介绍一下go-metrics中关于Meter的实现


请我喝瓶饮料

微信支付码

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据