prometheus的sdk client_golang 使用 定时器
之前线上监控的agent都是直接 time.Sleep(time.Duration(collectInterval) * time.Second) ,多少有些许的low,每次开始采集数据的时间都是从程序开始执行就开始采集,很显然这种偷懒的方式是不合理的。
1、普通的时间间隔示例
func AbNormalLoglistener(collectInterval int) {
abnormal_loglistener_Gauge := prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Namespace: "tc",
Subsystem: "serverMetricExtend",
Name: "abnormal_loglistener_log",
Help: "Loglistener An exception exists in the log file.",
},
[]string{
"hostname",
"alert_name",
},
)
prometheus.MustRegister(abnormal_loglistener_Gauge)
_t := tools.Server{}
sname := _t.GetServerHostName()
go func() {
defer func() {
if r := recover(); r != nil {
metricLog.Error(r)
}
}()
ticker := time.NewTicker(time.Duration(collectInterval) * time.Second)
now := time.Now()
nextMinute := now.Truncate(time.Duration(collectInterval) * time.Second).Add(time.Duration(collectInterval) * time.Second)
waitTime := nextMinute.Sub(now)
time.Sleep(waitTime)
for {
metricsBack := _t.FetchDirModTime()
for alert_name, status := range metricsBack{
abnormal_loglistener_Gauge.With(prometheus.Labels{"hostname": sname, "alert_name": alert_name}).Set(float64(status))
}
<-ticker.C
nextMinute = nextMinute.Add(time.Duration(collectInterval) * time.Second)
waitTime = nextMinute.Sub(time.Now())
time.Sleep(waitTime)
}
}()
}
2、方式一 time.Ticker
package main
import (
"fmt"
"time"
)
func main() {
// 创建一个定时器,每隔一分钟触发一次
ticker := time.NewTicker(time.Minute)
// 获取当前时间
now := time.Now()
// 计算下一分钟的开始时间
nextMinute := now.Truncate(time.Minute).Add(time.Minute)
// 计算需要等待的时间
waitTime := nextMinute.Sub(now)
// 等待到下一分钟的开始时间
time.Sleep(waitTime)
// 使用一个无限循环来控制方法的执行
for {
// 执行你的方法
fmt.Println("执行方法")
// 等待定时器的下一次触发事件
<-ticker.C
// 计算下一分钟的开始时间
nextMinute = nextMinute.Add(time.Minute)
// 计算需要等待的时间
waitTime = nextMinute.Sub(time.Now())
// 等待到下一分钟的开始时间
time.Sleep(waitTime)
}
}
3、方式二 time.Timer
package main
import (
"fmt"
"time"
)
func main() {
// 获取当前时间
now := time.Now()
// 计算下一分钟的开始时间
nextMinute := now.Truncate(time.Minute).Add(time.Minute)
// 计算需要等待的时间
waitTime := nextMinute.Sub(now)
// 创建一个定时器,在等待时间结束后执行任务
timer := time.NewTimer(waitTime)
// 使用一个无限循环来控制协程的执行
for {
<-timer.C // 等待定时器的触发事件
// 执行你的协程任务
go func() {
fmt.Println("执行协程任务")
// 在这里编写你的协程任务逻辑
}()
// 计算下一分钟的开始时间
nextMinute = nextMinute.Add(time.Minute)
// 重新计算需要等待的时间
waitTime = nextMinute.Sub(time.Now())
// 重置定时器
timer.Reset(waitTime)
}
}
4、这两种方式的区别,gpt给的答案,请各位自行斟酌
- time.NewTimer:
time.NewTimer 创建一个单次触发的定时器,它在指定的时间间隔过后触发一次。 适用于需要在指定时间间隔后执行一次操作的场景。 可以使用 timer.Reset 方法重新设置定时器的触发时间。
- time.NewTicker:
time.NewTicker 创建一个重复触发的定时器,它会以固定的时间间隔重复触发。 适用于需要定期执行某个操作的场景,比如每隔一段时间执行一次任务。 每次触发时,time.Ticker 类型的值会发送一个时间到其内部的通道 C,你可以使用 <-ticker.C 来等待触发事件。 可以使用 ticker.Stop 方法停止定时器的触发。
5、一些思考
m := time.Now().Truncate(time.Minute)
fmt.Printf("m:%s\n",m )
s := time.Now().Truncate(time.Duration(3600) * time.Second)
fmt.Printf("s:%s\n",s )
m:2023-08-08 11:56:00 +0800 CST
s:2023-08-08 11:00:00 +0800 CST
本文阅读量 次