用 Redis 分布式锁可解决多 Go 进程定时任务重复执行问题,核心是通过 SET key value EX seconds NX 原子命令实现唯一执行权控制,value 必须为唯一标识,过期时间设为任务最长执行时间的 2--3 倍,并用 Lua 脚本安全删锁。用 Redis 分布式锁控制任务唯一执行多个 Go 进程同时拉起定时任务时,cron 本身不带集群协调能力,直接跑就会重复触发。核心解法不是改调度逻辑,而是加一层"谁有资格执行"的判断------用 Redis 实现轻量级分布式锁最常用也最可控。常见错误现象:redis: nil(连接未初始化)、ERR value is not an integer or out of range(SET 命令参数错位)、锁没设过期时间导致死锁。用 SET key value EX seconds NX 原子写入,value 必须是唯一标识(比如主机名+pid),方便后续校验和清理过期时间(EX)建议设为任务最长执行时间的 2--3 倍,太短可能任务还没完锁就丢了,太长会拖慢故障恢复不要用 DEL key 直接删锁------得先 EVAL 脚本比对 value 再删,否则可能误删别人持有的锁Go 里推荐用 github.com/go-redis/redis/v9,它的 SetNX + SetEX 组合不如原生命令原子,老老实实用 Do 调 SET// 示例:获取锁ok, err := rdb.Do(ctx, "SET", "task:send_report", os.Getenv("HOSTNAME")+"-"+strconv.Itoa(os.Getpid()), "EX", "300", "NX").Bool()if err != nil || !ok { return // 没抢到锁,跳过本次执行}选对触发时机:避免 cron + 锁双重延迟很多人把 cron 和分布式锁叠在一起,结果发现任务总在预期时间之后几秒甚至几十秒才执行------问题出在"每个节点都按 cron 触发,再争锁",争锁失败的节点白白空转,还占资源。更稳的做法是只让一个节点负责"触发调度",其他节点只负责"执行"或"跳过"。典型结构:一个中心调度器(哪怕只是个固定 IP 的 Go 进程)按 cron 推送任务 ID 到 Redis List 或 Pub/Sub,所有工作节点监听并竞争执行权。立即学习"go语言免费学习笔记(深入)";如果用 redis.PubSub,注意 Go 客户端默认不重连,断连后收不到新消息,得手动监听 Subscribe 返回的 ErrClosed 并重建连接用 List(LPUSH + BRPOP)更可靠,但要注意 BRPOP 超时设置,别卡太久;任务体建议用 JSON 字符串,字段至少含 id、timeout、retry_count别在 cron 表达式里写 * * * * * 让所有节点每秒都去抢锁------这是典型的"高频率低收益"设计,压 Redis 还容易触发限流任务幂等性不能全靠锁兜底锁只能保证"同一时刻最多一个实例执行",但挡不住网络分区、进程崩溃、Redis 故障这些导致的"锁丢失+任务重试"。所以真正关键的是任务自身必须可重入。 Fotor AI Image Generator Fotor 平台的 AI 图片生成器
相关推荐
默_笙3 天前
🍙 给每个请求过安检:FastAPI 是怎么把校验写进类型注解的qq_426003963 天前
启动playwright录制codegen生成自动化测试脚本虎头金猫3 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺长沙三为智能科技3 天前
家政小程序开发从0到上线:五阶段交付流程与验收清单此时不提桶,更待何时3 天前
01-06-A-JVM排查实战详解伞伞悦读3 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__这个DBA有点耶3 天前
MVCC深入:Read View、版本链与快照读——InnoDB并发控制的内核DBA_G3 天前
从地面到云霄:GBase数据库在民航三大场景的落地实践自由能燃气设备3 天前
商用全预混低氮冷凝锅炉免费方案vs付费方案对比+选型避坑指南只睡四小时3 天前
Canvas 弹道联机实战:700 行 + 固定时间步长