44 lines
1.4 KiB
Go
44 lines
1.4 KiB
Go
package timer
|
||
|
||
import (
|
||
"fmt"
|
||
"math/rand"
|
||
"time"
|
||
|
||
"github.com/toolkits/pkg/logger"
|
||
|
||
"github.com/didi/nightingale/v5/models"
|
||
)
|
||
|
||
// UpdateAlias 对于上报的监控数据,会缓存在内存里,然后周期性更新其alias
|
||
// 主要是性能考虑,要不然每秒上报千万条监控指标,每条都去更新alias耗时太久
|
||
// server是无状态的,对于某个ident,如果刚开始上报alias1到server1,后来上报alias2到server2
|
||
// 如果server1和server2同时去更新数据库,可能会造成混乱,一会是alias1,一会是alias2
|
||
// 所以,models.UpdateAlias中做了一个逻辑,先清空了15s之前的数据,这样就可以保证只需要更新新数据即可
|
||
// go进程中的AliasMapper这个变量,在进程运行时间久了之后不知道是否会让内存持续增长而不释放
|
||
// 如果真的出现这个问题,可能要考虑把这个变量的存储放到redis之类的KV中
|
||
func UpdateAlias() {
|
||
go loopUpdateAlias()
|
||
}
|
||
|
||
func loopUpdateAlias() {
|
||
randtime := rand.Intn(2000)
|
||
fmt.Printf("timer: update alias: random sleep %dms\n", randtime)
|
||
time.Sleep(time.Duration(randtime) * time.Millisecond)
|
||
|
||
// 5s跑一次,只会使用最近15s有过更新的数据,在models.UpdateAlias有15s的清理逻辑
|
||
interval := time.Duration(5) * time.Second
|
||
|
||
for {
|
||
time.Sleep(interval)
|
||
updateAlias()
|
||
}
|
||
}
|
||
|
||
func updateAlias() {
|
||
err := models.UpdateAlias()
|
||
if err != nil {
|
||
logger.Warningf("UpdateAlias fail: %v", err)
|
||
}
|
||
}
|