Metrics的简易实现
版权声明 本站原创文章 由 萌叔 发表
转载请注明 萌叔 | 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的实现