必须显式调用config.NewFromYaml("machinery.yaml")初始化配置,路径、缩进、字段名(如broker非broker_url)、协议(redis://)、default_queue无空格/斜杠、Redis需pool_size等均需严格校验。

machinery 不会自动加载配置,必须显式调用 config.NewFromYaml;任务函数签名强制为 func(interface{}) error,错一个字符就 panic;worker 启动后“不干活”90% 是 broker 连接失败或队列名含空格——这些不是报错,而是静默卡住。
怎么初始化配置并确保 YAML 加载成功
machinery 从不读文件,config.NewFromYaml("machinery.yaml") 必须在 server.NewServer 之前调用。路径写错、缩进不齐、字段名拼错(比如写成 broker_url 而非 broker),都会导致 broker 字段为空,但不会报错——worker 启动后只打印 “waiting for tasks”,然后彻底挂起。
常见避坑点:
-
broker和result_backend的 URL 必须带协议,redis://123456@localhost:6379✅,localhost:6379❌ -
default_queue值不能含空格或斜杠,AMQP 下会直接报AMQP queue name invalid - 用了 Redis 就别漏掉
redis子段,尤其pool_size:默认是 5,高并发下连接耗尽,任务堆积却无提示 - YAML 文件名必须是
machinery.yaml(默认)或传入绝对路径,相对路径如"conf/machinery.yaml"需确认工作目录
注册和发送带参数的异步任务要注意什么
任务函数签名必须严格是 func(interface{}) error,返回值只能是 error。多一个返回值、返回 string 或 struct{},server.RegisterTask("xxx", fn) 就 panic,错误信息只说 “invalid task signature”,没提哪一行。
参数序列化也有隐性约束:
- time.Time 不能直接传,会序列化失败;改用
Unix()或Format("2006-01-02T15:04:05Z") - struct 字段要加
json:tag,否则 worker 收不到字段值 - nil 切片传过去变成
null,worker 端得主动判空,不能直接遍历 - 发送用
tasks.SendTaskWithContext,signature 里的Args是[]interface{},每个元素必须可 JSON 序列化
延迟任务和重试为什么总不生效
延迟靠 ETA 字段,它是一个 Unix 时间戳(秒级整数),不是“30秒后”。写成 time.Now().Add(30 * time.Second).Unix() ✅,写成 30 ❌(会被当成 1970 年时间戳,任务立刻触发或永远不触发)。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
重试默认完全关闭,必须手动设两个字段:
-
RetryCount: 3—— 最多重试次数 -
RetryTimeout: 60—— 每次重试间隔(秒),不是总超时
注意:重试状态不持久化。如果 worker 在重试中途重启,未完成的重试就丢了——machinery 只靠 broker 保活,没存重试计数到 backend。真要强保障,得自己加幂等 key + 主动查 GetState。
worker 启动后不消费任务,先查这三件事
别急着翻源码,90% 的问题出在这三个地方:
- broker 地址连不通:用
redis-cli -u redis://...或telnet localhost 5672直接测通断,别信日志里那句 “connected” - default_queue 名字和 worker 启动时指定的 queue 不一致:启动命令里
-q myqueue,但 YAML 里写的是default_queue: "my queue"(含空格)→ 绑定失败 - AMQP 场景下没声明 queue:machinery 不自动声明,得提前用 rabbitmqctl 或代码确保 queue 存在且 durable=true
最隐蔽的坑是:Redis broker 下,如果 broker URL 密码含特殊字符(比如 @ 或 /),URL 解析会截断,实际连的是错误地址——务必用 URL 编码处理密码。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










