refactor: 优化指标统计逻辑,减少锁的使用,提高性能
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
@@ -10,13 +9,12 @@ import (
|
||||
// 只针对转发请求调用 Inc。
|
||||
|
||||
type bucket struct {
|
||||
second int64 // Unix 秒
|
||||
count int64
|
||||
second atomic.Int64 // Unix 秒
|
||||
count atomic.Int64
|
||||
}
|
||||
|
||||
var (
|
||||
buckets [60]bucket
|
||||
mu sync.Mutex
|
||||
total atomic.Int64
|
||||
)
|
||||
|
||||
@@ -24,14 +22,18 @@ var (
|
||||
func Inc() {
|
||||
now := time.Now().Unix()
|
||||
idx := now % 60
|
||||
mu.Lock()
|
||||
b := &buckets[idx]
|
||||
if b.second != now { // 该槽位属于旧秒,重置
|
||||
b.second = now
|
||||
b.count = 0
|
||||
for {
|
||||
sec := b.second.Load()
|
||||
if sec == now {
|
||||
b.count.Add(1)
|
||||
break
|
||||
}
|
||||
if b.second.CompareAndSwap(sec, now) {
|
||||
b.count.Store(1)
|
||||
break
|
||||
}
|
||||
}
|
||||
b.count++
|
||||
mu.Unlock()
|
||||
total.Add(1)
|
||||
}
|
||||
|
||||
@@ -39,10 +41,8 @@ func Inc() {
|
||||
func QPS() int64 {
|
||||
now := time.Now().Unix()
|
||||
idx := now % 60
|
||||
mu.Lock()
|
||||
b := buckets[idx]
|
||||
mu.Unlock()
|
||||
if b.second == now { return b.count }
|
||||
b := &buckets[idx]
|
||||
if b.second.Load() == now { return b.count.Load() }
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -50,14 +50,12 @@ func QPS() int64 {
|
||||
func QPM() int64 {
|
||||
now := time.Now().Unix()
|
||||
var sum int64
|
||||
mu.Lock()
|
||||
for i := 0; i < 60; i++ {
|
||||
b := buckets[i]
|
||||
if now-b.second < 60 { // 在窗口内
|
||||
sum += b.count
|
||||
for i := range 60 {
|
||||
sec := buckets[i].second.Load()
|
||||
if sec <= now && now-sec < 60 { // 在窗口内
|
||||
sum += buckets[i].count.Load()
|
||||
}
|
||||
}
|
||||
mu.Unlock()
|
||||
return sum
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user