用 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 图片生成器
相关推荐
ai小陈1 小时前
PyTorch DataLoader数据加载性能排查:GPU利用率低的实操指南2601_962299244 小时前
Azure python操作系统列表知行合一。。。4 小时前
RAG--03--Milvus基本用法TDengine (老段)4 小时前
TDengine 线程模型 — 网络、调度、执行学术 学术 Fun5 小时前
如何用 API 与 Webhook 批量把图表图片转换成 VSDX上学的小垃圾5 小时前
01-数据库系统概述2601_962100545 小时前
python包和模块的内容整理二进制漫游记6 小时前
FastAPI项目集成 Qdrant向量数据库+阿里云Embedding完整实战(工具封装+业务调用)2501_928996226 小时前
GPT-4o换DeepSeek迁移成本多少?中科热备解析API聚合平台技术账本-今昭-6 小时前
《V2V 迁移实战:将 VMware 虚拟机转为 OpenStack 可用 Glance qcow2 镜像》