Skip to content

Commit cf8693a

Browse files
committed
Update.
1 parent 5f2a3ad commit cf8693a

4 files changed

Lines changed: 85 additions & 52 deletions

File tree

model/alertrule.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,15 @@ const (
1313
)
1414

1515
type CycleTransferStats struct {
16-
Name string
17-
From time.Time
18-
To time.Time
19-
Max uint64
20-
Min uint64
21-
ServerName map[uint64]string
22-
Transfer map[uint64]uint64
23-
NextUpdate map[uint64]time.Time
16+
Name string
17+
From time.Time
18+
To time.Time
19+
Max uint64
20+
Min uint64
21+
ServerName map[uint64]string
22+
Transfer map[uint64]uint64
23+
NextUpdate map[uint64]time.Time // 下次检查时间
24+
LastResetTime map[uint64]time.Time // 上次重置时间(用于判断是否需要重置)
2425
}
2526

2627
type AlertRule struct {

model/server.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ type Server struct {
4747
// 累计流量数据
4848
CumulativeNetInTransfer uint64 `gorm:"default:0" json:"cumulative_net_in_transfer"` // 累计入站使用量
4949
CumulativeNetOutTransfer uint64 `gorm:"default:0" json:"cumulative_net_out_transfer"` // 累计出站使用量
50+
LastTrafficResetTime time.Time `gorm:"type:datetime" json:"last_traffic_reset_time"` // 最后一次流量重置时间
5051
LastFlowSaveTime time.Time `gorm:"-" json:"-"` // 最后一次保存流量数据的时间
5152
LastDBUpdateTime time.Time `gorm:"-" json:"-"` // 最后一次数据库更新时间
5253
}
@@ -64,6 +65,7 @@ func (s *Server) CopyFromRunningServer(old *Server) {
6465
s.IsOnline = old.IsOnline
6566
s.CumulativeNetInTransfer = old.CumulativeNetInTransfer
6667
s.CumulativeNetOutTransfer = old.CumulativeNetOutTransfer
68+
s.LastTrafficResetTime = old.LastTrafficResetTime
6769
s.LastFlowSaveTime = old.LastFlowSaveTime
6870

6971
// 注意:不要复制配置相关的字段,因为这些可能已经在编辑时更新了

service/rpc/server.go

Lines changed: 60 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -971,72 +971,101 @@ func checkAndResetCycleTraffic(clientID uint64) {
971971

972972
currentCycleStart := transferRule.GetTransferDurationStart()
973973
currentCycleEnd := transferRule.GetTransferDurationEnd()
974+
singleton.AlertsLock.RUnlock()
974975

975-
// 读取上次重置参考时间(仍在读锁下,随后立即释放)
976-
lastResetTime := time.Time{}
977-
hasNextUpdate := false
978-
if stats, exists := singleton.AlertsCycleTransferStatsStore[matchingAlert.ID]; exists && stats != nil {
979-
if nu, has := stats.NextUpdate[clientID]; has {
980-
hasNextUpdate = true
981-
// 如果NextUpdate在当前周期开始之前,说明是上个周期的记录,可以作为重置参考
982-
if nu.Before(currentCycleStart) {
983-
lastResetTime = nu
984-
}
985-
}
976+
// 2) 读取服务器的上次重置时间(从持久化字段)
977+
singleton.ServerLock.RLock()
978+
server := singleton.ServerList[clientID]
979+
if server == nil {
980+
singleton.ServerLock.RUnlock()
981+
return
986982
}
987-
singleton.AlertsLock.RUnlock()
983+
lastResetTime := server.LastTrafficResetTime
984+
singleton.ServerLock.RUnlock()
988985

989-
// 2) 判断是否需要重置(锁外计算)
986+
// 3) 判断是否需要重置(锁外计算)
990987
needReset := false
991988
now := time.Now()
992989

993-
// 重置条件:有NextUpdate记录且lastResetTime在当前周期之前
994-
if hasNextUpdate && now.After(currentCycleStart) && !lastResetTime.IsZero() && lastResetTime.Before(currentCycleStart) {
990+
// 重置条件:上次重置时间在当前周期开始之前
991+
// 如果LastTrafficResetTime为零值(从未重置过),则初始化为当前周期起点
992+
if lastResetTime.IsZero() {
993+
// 首次检测,将重置时间初始化为当前周期起点,避免启动时误触发
994+
singleton.ServerLock.Lock()
995+
if svr := singleton.ServerList[clientID]; svr != nil {
996+
svr.LastTrafficResetTime = currentCycleStart
997+
log.Printf("[周期流量初始化] 服务器ID=%d 初始化重置时间为当前周期起点: %s",
998+
clientID, currentCycleStart.Format("2006-01-02 15:04:05"))
999+
1000+
// 持久化到数据库
1001+
if singleton.Conf.DatabaseType == "badger" {
1002+
if db.DB != nil {
1003+
serverOps := db.NewServerOps(db.DB)
1004+
if dbServer, err := serverOps.GetServer(clientID); err == nil && dbServer != nil {
1005+
dbServer.LastTrafficResetTime = currentCycleStart
1006+
_ = serverOps.SaveServer(dbServer)
1007+
}
1008+
}
1009+
} else if singleton.DB != nil {
1010+
_ = singleton.DB.Model(&model.Server{}).Where("id = ?", clientID).
1011+
Update("last_traffic_reset_time", currentCycleStart).Error
1012+
}
1013+
}
1014+
singleton.ServerLock.Unlock()
1015+
return
1016+
}
1017+
1018+
// 检查是否需要重置:上次重置在当前周期之前
1019+
if lastResetTime.Before(currentCycleStart) && now.After(currentCycleStart) {
9951020
needReset = true
1021+
log.Printf("[周期流量重置] 服务器ID=%d 触发重置: 上次重置时间=%s 在当前周期 %s 之前",
1022+
clientID, lastResetTime.Format("2006-01-02 15:04:05"), currentCycleStart.Format("2006-01-02 15:04:05"))
9961023
}
9971024

9981025
if !needReset {
9991026
return
10001027
}
10011028

1002-
// 3) 重置累计流量(写锁仅包裹修改内存状态)
1029+
// 4) 重置累计流量(写锁仅包裹修改内存状态)
10031030
singleton.ServerLock.Lock()
1004-
server := singleton.ServerList[clientID]
1005-
if server == nil {
1031+
resetServer := singleton.ServerList[clientID]
1032+
if resetServer == nil {
10061033
singleton.ServerLock.Unlock()
10071034
return
10081035
}
1009-
oldInTransfer := server.CumulativeNetInTransfer
1010-
oldOutTransfer := server.CumulativeNetOutTransfer
1011-
serverName := server.Name
1036+
oldInTransfer := resetServer.CumulativeNetInTransfer
1037+
oldOutTransfer := resetServer.CumulativeNetOutTransfer
1038+
serverName := resetServer.Name
10121039
serverIP := ""
1013-
if server.Host != nil {
1014-
serverIP = server.Host.IP
1040+
if resetServer.Host != nil {
1041+
serverIP = resetServer.Host.IP
10151042
}
10161043

1017-
server.CumulativeNetInTransfer = 0
1018-
server.CumulativeNetOutTransfer = 0
1019-
server.PrevTransferInSnapshot = 0
1020-
server.PrevTransferOutSnapshot = 0
1044+
resetServer.CumulativeNetInTransfer = 0
1045+
resetServer.CumulativeNetOutTransfer = 0
1046+
resetServer.PrevTransferInSnapshot = 0
1047+
resetServer.PrevTransferOutSnapshot = 0
1048+
resetServer.LastTrafficResetTime = now // 更新重置时间
10211049
singleton.ServerLock.Unlock()
10221050

1023-
// 4) 持久化到数据库(锁外)
1051+
// 5) 持久化到数据库(锁外)
10241052
if singleton.Conf.DatabaseType == "badger" {
10251053
if db.DB != nil {
10261054
serverOps := db.NewServerOps(db.DB)
10271055
if dbServer, err := serverOps.GetServer(clientID); err == nil && dbServer != nil {
10281056
dbServer.CumulativeNetInTransfer = 0
10291057
dbServer.CumulativeNetOutTransfer = 0
1058+
dbServer.LastTrafficResetTime = now
10301059
_ = serverOps.SaveServer(dbServer) // 静默处理错误,避免打扰热路径
10311060
}
10321061
}
10331062
} else {
10341063
if singleton.DB != nil {
1035-
_ = singleton.DB.Exec("UPDATE servers SET cumulative_net_in_transfer = 0, cumulative_net_out_transfer = 0 WHERE id = ?", clientID).Error
1064+
_ = singleton.DB.Exec("UPDATE servers SET cumulative_net_in_transfer = 0, cumulative_net_out_transfer = 0, last_traffic_reset_time = ? WHERE id = ?", now, clientID).Error
10361065
}
10371066
}
10381067

1039-
// 5) 更新周期统计存储(需要写锁)
1068+
// 6) 更新周期统计存储(需要写锁)
10401069
singleton.AlertsLock.Lock()
10411070
if stats, exists := singleton.AlertsCycleTransferStatsStore[matchingAlert.ID]; exists && stats != nil {
10421071
if stats.NextUpdate == nil {
@@ -1052,7 +1081,7 @@ func checkAndResetCycleTraffic(clientID uint64) {
10521081
}
10531082
singleton.AlertsLock.Unlock()
10541083

1055-
// 6) 发送通知(锁外)
1084+
// 7) 发送通知(锁外)
10561085
formatTraffic := func(bytes uint64) string {
10571086
const unit = 1024
10581087
if bytes < unit {

service/singleton/alertsentinel.go

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,15 @@ func addCycleTransferStatsInfo(alert *model.AlertRule) {
4646
from := alert.Rules[j].GetTransferDurationStart()
4747
to := alert.Rules[j].GetTransferDurationEnd()
4848
AlertsCycleTransferStatsStore[alert.ID] = &model.CycleTransferStats{
49-
Name: alert.Name,
50-
From: from,
51-
To: to,
52-
Max: uint64(alert.Rules[j].Max),
53-
Min: uint64(alert.Rules[j].Min),
54-
ServerName: make(map[uint64]string),
55-
Transfer: make(map[uint64]uint64),
56-
NextUpdate: make(map[uint64]time.Time),
49+
Name: alert.Name,
50+
From: from,
51+
To: to,
52+
Max: uint64(alert.Rules[j].Max),
53+
Min: uint64(alert.Rules[j].Min),
54+
ServerName: make(map[uint64]string),
55+
Transfer: make(map[uint64]uint64),
56+
NextUpdate: make(map[uint64]time.Time),
57+
LastResetTime: make(map[uint64]time.Time),
5758
}
5859
}
5960
}
@@ -350,7 +351,7 @@ func checkStatus() {
350351
}
351352
continue
352353
}
353-
354+
354355
// 初始化每个Rule的字段,避免nil指针
355356
for i := range alert.Rules {
356357
if alert.Rules[i].NextTransferAt == nil {
@@ -372,7 +373,7 @@ func checkStatus() {
372373
}
373374
continue
374375
}
375-
376+
376377
// 安全检查:确保alert不为nil
377378
if alert == nil {
378379
if Conf.Debug {
@@ -409,7 +410,7 @@ func checkStatus() {
409410
// SQLite模式下,传入DB参数
410411
snapshot = alert.Snapshot(cycleStats, server, DB)
411412
}
412-
413+
413414
// 安全检查:确保snapshot不为nil
414415
if snapshot == nil {
415416
snapshot = make([]interface{}, 0)
@@ -1197,7 +1198,7 @@ func generateThresholdAlertMessage(alert *model.AlertRule, server *model.Server,
11971198
}
11981199

11991200
usagePercent := float64(currentUsage) / rule.Max * 100
1200-
1201+
12011202
// 根据实际使用百分比生成动态标题
12021203
var dynamicTitle string
12031204
if usagePercent >= 100 {
@@ -1207,7 +1208,7 @@ func generateThresholdAlertMessage(alert *model.AlertRule, server *model.Server,
12071208
} else {
12081209
dynamicTitle = fmt.Sprintf("%.1f%%流量使用提醒", usagePercent)
12091210
}
1210-
1211+
12111212
message := fmt.Sprintf("%s %s\n", icon, dynamicTitle)
12121213
message += fmt.Sprintf("时间: %s\n", now.Format("2006-01-02 15:04:05"))
12131214
message += fmt.Sprintf("服务器: %s\n", server.Name)

0 commit comments

Comments
 (0)