1. 策略心跳机制的作用
周期性地向Redis存储策略的心跳信息,并且可以通过上下文(context
)来控制该机制的启动和停止。
心跳机制可以帮助系统及时清理无效连接或僵尸进程。例如,通过Redis存储心跳信息,若策略长时间未更新状态,监控系统可判定其异常并回收资源,避免内存泄漏或连接池耗尽。
2. StrategyHeartbeat实现
ctx := context.Background()
go atom.StrategyHeartbeatForever(ctx, ac.StrategyConfig)
context.Background()
:创建一个空的上下文(context
),通常作为根上下文使用,可用于传递请求范围的数据、取消信号和截止时间等。go atom.StrategyHeartbeatForever(ctx, ac.StrategyConfig)
:以goroutine的方式异步调用StrategyHeartbeatForever
函数,这样不会阻塞当前程序的执行。传入的参数包括上下文ctx
和策略配置ac.StrategyConfig
。
func StrategyHeartbeatForever(ctx context.Context, cfg *StrategyConfig) {
ticker := time.NewTicker(StrategyHeartbeatInterval)
rds, err := NewRedisPool(cfg.System.CacheRedis, 1, 1)
if err != nil {
utilLog.Errorf("StrategyHeartbeatForever redis error:%s", err.Error())
}
heartbeatKey := fmt.Sprintf("heartbeat:strategy:%s", cfg.Strategy.Name)
utilLog.Infof("[hb start] key=%s interval=%.0f", heartbeatKey, StrategyHeartbeatInterval.Seconds())
for {
select {
case <-ctx.Done():
ticker.Stop()
_ = rds.Close()
utilLog.Info("exit heartbeat handler by context")
return
case <-ticker.C:
msg := strategyHeartbeatMessage{
TimeMs: time.Now().UnixMilli(),
Success: true,
Type: "hb",
ActionTime: 0,
ErrorMessage: "",
}
handler := rds.Get()
msgBytes, _ := Json.Marshal(msg)
_, _ = handler.Do("SET", heartbeatKey, msgBytes)
_ = handler.Close()
}
}
}
代码具体功能解释
- 定时器初始化:
ticker := time.NewTicker(StrategyHeartbeatInterval)
:创建一个定时器,每隔StrategyHeartbeatInterval
时间触发一次。
- Redis连接池初始化:
rds, err := NewRedisPool(cfg.System.CacheRedis, 1, 1)
:创建一个Redis连接池,如果创建过程中出现错误,会使用日志记录错误信息。
- 心跳键生成:
heartbeatKey := fmt.Sprintf("heartbeat:strategy:%s", cfg.Strategy.Name)
:根据策略名称生成Redis的键,用于存储心跳信息。
- 日志记录:
utilLog.Infof("[hb start] key=%s interval=%.0f", heartbeatKey, StrategyHeartbeatInterval.Seconds())
:记录心跳机制启动的日志,包含心跳键和心跳间隔时间。
- 主循环:
for {}
:进入一个无限循环,不断监听上下文的取消信号和定时器的触发信号。case <-ctx.Done()
:当接收到上下文的取消信号时,停止定时器,关闭Redis连接池,并记录退出日志,然后返回。case <-ticker.C
:当定时器触发时,执行以下操作:- 创建一个
strategyHeartbeatMessage
结构体的实例msg
,包含当前时间戳、成功标志、消息类型等信息。 - 从Redis连接池中获取一个连接
handler
。 - 将
msg
结构体序列化为JSON字节数组msgBytes
。 - 使用Redis的
SET
命令将心跳信息存储到Redis中。 - 关闭Redis连接。
- 创建一个
总结
这段代码实现了一个持续运行的策略心跳机制,通过定时器周期性地向Redis存储策略的心跳信息,并且可以通过上下文来控制该机制的停止,确保在程序关闭或需要停止心跳时能够正确清理资源。