限制单个服务每次上传的域名统计数不超过20个

This commit is contained in:
刘祥超
2023-03-22 19:05:10 +08:00
parent e6ab98ad11
commit 613acbff95
3 changed files with 61 additions and 32 deletions

View File

@@ -10,22 +10,22 @@ import (
func TestBandwidthStatManager_Add(t *testing.T) { func TestBandwidthStatManager_Add(t *testing.T) {
var manager = stats.NewBandwidthStatManager() var manager = stats.NewBandwidthStatManager()
manager.Add(1, 1, 10, 10) manager.AddBandwidth(1, 1, 10, 10)
manager.Add(1, 1, 10, 10) manager.AddBandwidth(1, 1, 10, 10)
manager.Add(1, 1, 10, 10) manager.AddBandwidth(1, 1, 10, 10)
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)
manager.Add(1, 1, 85, 85) manager.AddBandwidth(1, 1, 85, 85)
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)
manager.Add(1, 1, 25, 25) manager.AddBandwidth(1, 1, 25, 25)
manager.Add(1, 1, 75, 75) manager.AddBandwidth(1, 1, 75, 75)
manager.Inspect() manager.Inspect()
} }
func TestBandwidthStatManager_Loop(t *testing.T) { func TestBandwidthStatManager_Loop(t *testing.T) {
var manager = stats.NewBandwidthStatManager() var manager = stats.NewBandwidthStatManager()
manager.Add(1, 1, 10, 10) manager.AddBandwidth(1, 1, 10, 10)
manager.Add(1, 1, 10, 10) manager.AddBandwidth(1, 1, 10, 10)
manager.Add(1, 1, 10, 10) manager.AddBandwidth(1, 1, 10, 10)
err := manager.Loop() err := manager.Loop()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)

View File

@@ -12,6 +12,7 @@ import (
"github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/maps" "github.com/iwind/TeaGo/maps"
"github.com/iwind/TeaGo/types" "github.com/iwind/TeaGo/types"
"sort"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@@ -45,7 +46,7 @@ const trafficStatsMaxLife = 1200 // 最大只保存20分钟内的数据
// TrafficStatManager 区域流量统计 // TrafficStatManager 区域流量统计
type TrafficStatManager struct { type TrafficStatManager struct {
itemMap map[string]*TrafficItem // [timestamp serverId] => *TrafficItem itemMap map[string]*TrafficItem // [timestamp serverId] => *TrafficItem
domainsMap map[string]*TrafficItem // timestamp @ serverId @ domain => *TrafficItem domainsMap map[int64]map[string]*TrafficItem // serverIde => { timestamp @ domain => *TrafficItem }
pbItems []*pb.ServerDailyStat pbItems []*pb.ServerDailyStat
pbDomainItems []*pb.UploadServerDailyStatsRequest_DomainStat pbDomainItems []*pb.UploadServerDailyStatsRequest_DomainStat
@@ -59,7 +60,7 @@ type TrafficStatManager struct {
func NewTrafficStatManager() *TrafficStatManager { func NewTrafficStatManager() *TrafficStatManager {
var manager = &TrafficStatManager{ var manager = &TrafficStatManager{
itemMap: map[string]*TrafficItem{}, itemMap: map[string]*TrafficItem{},
domainsMap: map[string]*TrafficItem{}, domainsMap: map[int64]map[string]*TrafficItem{},
} }
return manager return manager
@@ -140,11 +141,17 @@ func (this *TrafficStatManager) Add(serverId int64, domain string, bytes int64,
item.PlanId = planId item.PlanId = planId
// 单个域名流量 // 单个域名流量
var domainKey = strconv.FormatInt(timestamp, 10) + "@" + strconv.FormatInt(serverId, 10) + "@" + domain var domainKey = types.String(timestamp) + "@" + domain
domainItem, ok := this.domainsMap[domainKey] serverDomainMap, ok := this.domainsMap[serverId]
if !ok {
serverDomainMap = map[string]*TrafficItem{}
this.domainsMap[serverId] = serverDomainMap
}
domainItem, ok := serverDomainMap[domainKey]
if !ok { if !ok {
domainItem = &TrafficItem{} domainItem = &TrafficItem{}
this.domainsMap[domainKey] = domainItem serverDomainMap[domainKey] = domainItem
} }
domainItem.Bytes += bytes domainItem.Bytes += bytes
domainItem.CachedBytes += cachedBytes domainItem.CachedBytes += cachedBytes
@@ -176,7 +183,7 @@ func (this *TrafficStatManager) Upload() error {
// reset // reset
this.itemMap = map[string]*TrafficItem{} this.itemMap = map[string]*TrafficItem{}
this.domainsMap = map[string]*TrafficItem{} this.domainsMap = map[int64]map[string]*TrafficItem{}
this.locker.Unlock() this.locker.Unlock()
@@ -208,15 +215,21 @@ func (this *TrafficStatManager) Upload() error {
} }
// 域名统计 // 域名统计
const maxDomainsPerServer = 20
var pbDomainStats = []*pb.UploadServerDailyStatsRequest_DomainStat{} var pbDomainStats = []*pb.UploadServerDailyStatsRequest_DomainStat{}
for key, item := range domainMap { for serverId, serverDomainMap := range domainMap {
var pieces = strings.SplitN(key, "@", 3) // 如果超过单个服务最大值则只取前N个
if len(pieces) != 3 { var shouldTrim = len(serverDomainMap) > maxDomainsPerServer
var tempItems []*pb.UploadServerDailyStatsRequest_DomainStat
for key, item := range serverDomainMap {
var pieces = strings.SplitN(key, "@", 2)
if len(pieces) != 2 {
continue continue
} }
pbDomainStats = append(pbDomainStats, &pb.UploadServerDailyStatsRequest_DomainStat{ var pbItem = &pb.UploadServerDailyStatsRequest_DomainStat{
ServerId: types.Int64(pieces[1]), ServerId: serverId,
Domain: pieces[2], Domain: pieces[1],
Bytes: item.Bytes, Bytes: item.Bytes,
CachedBytes: item.CachedBytes, CachedBytes: item.CachedBytes,
CountRequests: item.CountRequests, CountRequests: item.CountRequests,
@@ -224,7 +237,21 @@ func (this *TrafficStatManager) Upload() error {
CountAttackRequests: item.CountAttackRequests, CountAttackRequests: item.CountAttackRequests,
AttackBytes: item.AttackBytes, AttackBytes: item.AttackBytes,
CreatedAt: types.Int64(pieces[0]), CreatedAt: types.Int64(pieces[0]),
}
if !shouldTrim {
pbDomainStats = append(pbDomainStats, pbItem)
} else {
tempItems = append(tempItems, pbItem)
}
}
if shouldTrim {
sort.Slice(tempItems, func(i, j int) bool {
return tempItems[i].CountRequests > tempItems[j].CountRequests
}) })
pbDomainStats = append(pbDomainStats, tempItems[:maxDomainsPerServer]...)
}
} }
// 历史未提交记录 // 历史未提交记录

View File

@@ -1,6 +1,8 @@
package stats package stats
import ( import (
"github.com/iwind/TeaGo/rands"
"github.com/iwind/TeaGo/types"
"runtime" "runtime"
"testing" "testing"
) )
@@ -16,7 +18,7 @@ func TestTrafficStatManager_Add(t *testing.T) {
func TestTrafficStatManager_Upload(t *testing.T) { func TestTrafficStatManager_Upload(t *testing.T) {
manager := NewTrafficStatManager() manager := NewTrafficStatManager()
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {
manager.Add(1, "goedge.cn", 1, 0, 0, 0, 0, 0, false, 0) manager.Add(1, "goedge.cn"+types.String(rands.Int(0, 10)), 1, 0, 1, 0, 0, 0, false, 0)
} }
err := manager.Upload() err := manager.Upload()
if err != nil { if err != nil {