@@ -515,21 +515,25 @@ func (s *ServerHandler) processServerStateWithoutLock(clientID uint64, serverCop
515515 // 检查周期流量重置
516516 checkAndResetCycleTraffic (clientID )
517517
518- // 检查是否是服务器重启或网络接口重置
518+ // 检查是否是服务器重启或网络接口重置 - 优化频繁重启场景
519519 isRestart := false
520520 if serverCopy .Host != nil && prevState != nil {
521521 // 获取之前显示的累计流量值
522522 prevDisplayIn := prevState .NetInTransfer
523523 prevDisplayOut := prevState .NetOutTransfer
524524
525- // 修改流量回退检测逻辑,增加容错范围
526- if (prevDisplayIn > 0 && originalNetInTransfer < prevDisplayIn && float64 (prevDisplayIn - originalNetInTransfer )/ float64 (prevDisplayIn ) < 0.1 ) ||
527- (prevDisplayOut > 0 && originalNetOutTransfer < prevDisplayOut && float64 (prevDisplayOut - originalNetOutTransfer )/ float64 (prevDisplayOut ) < 0.1 ) {
528- isRestart = false
529- } else if (prevDisplayIn > 0 && originalNetInTransfer < prevDisplayIn / 2 ) ||
530- (prevDisplayOut > 0 && originalNetOutTransfer < prevDisplayOut / 2 ) {
531- isRestart = true
525+ // 优化重启检测逻辑,减少频繁重启时的误判
526+ // 只有在流量大幅回退(超过80%)且上次活跃时间超过5分钟时才认为是重启
527+ timeSinceLastActive := now .Sub (serverCopy .LastActive )
528+
529+ if timeSinceLastActive > 5 * time .Minute {
530+ // 长时间离线后重新上线,检查流量回退
531+ if (prevDisplayIn > 0 && originalNetInTransfer < prevDisplayIn / 5 ) ||
532+ (prevDisplayOut > 0 && originalNetOutTransfer < prevDisplayOut / 5 ) {
533+ isRestart = true
534+ }
532535 }
536+ // 短时间内的重连不认为是重启,继续累加流量
533537 }
534538
535539 // 准备数据库更新数据
@@ -674,11 +678,15 @@ func (s *ServerHandler) updateTrafficIncremental(server *model.Server, state *mo
674678 backwardAmount := prevIn - originalNetInTransfer
675679 backwardPercent := float64 (backwardAmount ) / float64 (prevIn + 1 )
676680
677- if backwardPercent < 0.05 { // 从10%降低到5%,减少误判
678- // 小幅度回退,可能是统计误差,不计入增量
681+ if backwardPercent < 0.02 { // 进一步降低到2%,减少频繁重启时的误判
682+ // 极小幅度回退,可能是统计误差,不计入增量
683+ increaseIn = 0
684+ } else if backwardPercent < 0.5 {
685+ // 中等幅度回退,可能是频繁重启,保持累计流量,只重置基准点
686+ server .PrevTransferInSnapshot = int64 (originalNetInTransfer )
679687 increaseIn = 0
680688 } else {
681- // 大幅度回退,可能是重启 ,重置基准点
689+ // 大幅度回退,确实是重启 ,重置基准点
682690 server .PrevTransferInSnapshot = int64 (originalNetInTransfer )
683691 increaseIn = 0
684692 }
@@ -706,11 +714,15 @@ func (s *ServerHandler) updateTrafficIncremental(server *model.Server, state *mo
706714 backwardAmount := prevOut - originalNetOutTransfer
707715 backwardPercent := float64 (backwardAmount ) / float64 (prevOut + 1 )
708716
709- if backwardPercent < 0.05 { // 从10%降低到5%,减少误判
710- // 小幅度回退,可能是统计误差,不计入增量
717+ if backwardPercent < 0.02 { // 进一步降低到2%,减少频繁重启时的误判
718+ // 极小幅度回退,可能是统计误差,不计入增量
719+ increaseOut = 0
720+ } else if backwardPercent < 0.5 {
721+ // 中等幅度回退,可能是频繁重启,保持累计流量,只重置基准点
722+ server .PrevTransferOutSnapshot = int64 (originalNetOutTransfer )
711723 increaseOut = 0
712724 } else {
713- // 大幅度回退,可能是重启 ,重置基准点
725+ // 大幅度回退,确实是重启 ,重置基准点
714726 server .PrevTransferOutSnapshot = int64 (originalNetOutTransfer )
715727 increaseOut = 0
716728 }
@@ -799,33 +811,41 @@ func (s *ServerHandler) ReportSystemInfo(c context.Context, r *pb.Host) (*pb.Rec
799811 /**
800812 * 这里的 singleton 中的数据都是关机前的旧数据
801813 * 当 agent 重启时,bootTime 变大,agent 端会先上报 host 信息,然后上报 state 信息
802- * 这是可以借助上报顺序的空档,标记服务器为重启状态,表示从该节点开始累计流量
814+ * 优化:只有在 BootTime 显著变化时才认为是真正的重启
803815 */
804- if singleton .ServerList [clientID ].Host != nil && singleton .ServerList [clientID ].Host .BootTime < host .BootTime {
805- // 服务器重启时保持累计流量不变,只重置上次记录点
806- singleton .ServerList [clientID ].PrevTransferInSnapshot = 0
807- singleton .ServerList [clientID ].PrevTransferOutSnapshot = 0
816+ if singleton .ServerList [clientID ].Host != nil {
817+ oldBootTime := singleton .ServerList [clientID ].Host .BootTime
818+ bootTimeDiff := host .BootTime - oldBootTime
808819
809- // 确保从数据库读取最新的累计流量值(只在重启时读取一次)
810- if singleton .Conf .DatabaseType == "badger" {
811- // 使用BadgerDB读取累计流量
812- if db .DB != nil {
813- serverOps := db .NewServerOps (db .DB )
814- if server , err := serverOps .GetServer (clientID ); err == nil && server != nil {
815- singleton .ServerList [clientID ].CumulativeNetInTransfer = server .CumulativeNetInTransfer
816- singleton .ServerList [clientID ].CumulativeNetOutTransfer = server .CumulativeNetOutTransfer
820+ // 只有在 BootTime 显著增加(超过1小时)或减少时才认为是重启
821+ // 这样可以避免频繁重启或时间同步问题导致的误判
822+ if bootTimeDiff > 3600 || bootTimeDiff < 0 {
823+ // 真正的重启:保持累计流量不变,只重置上次记录点
824+ singleton .ServerList [clientID ].PrevTransferInSnapshot = 0
825+ singleton .ServerList [clientID ].PrevTransferOutSnapshot = 0
826+
827+ // 确保从数据库读取最新的累计流量值(只在重启时读取一次)
828+ if singleton .Conf .DatabaseType == "badger" {
829+ // 使用BadgerDB读取累计流量
830+ if db .DB != nil {
831+ serverOps := db .NewServerOps (db .DB )
832+ if server , err := serverOps .GetServer (clientID ); err == nil && server != nil {
833+ singleton .ServerList [clientID ].CumulativeNetInTransfer = server .CumulativeNetInTransfer
834+ singleton .ServerList [clientID ].CumulativeNetOutTransfer = server .CumulativeNetOutTransfer
835+ }
817836 }
818- }
819- } else {
820- // 使用SQLite读取累计流量
821- if singleton . DB != nil {
822- var server model. Server
823- if err := singleton .DB . First ( & server , clientID ). Error ; err == nil {
824- singleton .ServerList [clientID ].CumulativeNetInTransfer = server .CumulativeNetInTransfer
825- singleton . ServerList [ clientID ]. CumulativeNetOutTransfer = server . CumulativeNetOutTransfer
837+ } else {
838+ // 使用SQLite读取累计流量
839+ if singleton . DB != nil {
840+ var server model. Server
841+ if err := singleton . DB . First ( & server , clientID ). Error ; err == nil {
842+ singleton .ServerList [ clientID ]. CumulativeNetInTransfer = server . CumulativeNetInTransfer
843+ singleton .ServerList [clientID ].CumulativeNetOutTransfer = server .CumulativeNetOutTransfer
844+ }
826845 }
827846 }
828847 }
848+ // 小幅度的 BootTime 变化不认为是重启,继续正常累加流量
829849 }
830850
831851 // 不要冲掉国家码
0 commit comments