machinery需手动初始化配置、注册任务并启动worker,缺一不可;须调用config.newfromyaml指定正确路径和格式的machinery.yaml,broker与result_backend需带完整协议,任务函数签名必须为func(interface{}) error,延迟任务用eta字段,重试需显式设置retrycount和retrytimeout。

Machinery 不是开箱即用的库,必须显式加载配置、注册任务、启动 worker,缺一不可;否则你会看到 worker 启动后卡在 waiting for tasks,却完全不知道哪步漏了。
怎么初始化配置并加载 machinery.yaml
machinery 不会自动读 machinery.yaml,必须手动调用 config.NewFromYaml("machinery.yaml")。路径错、缩进乱、字段名拼错(比如写成 result_backend 却少了个下划线),都会导致静默失败——broker 为空也不报错,但 worker 就再也收不到任务。
-
machinery.yaml必须放在可读路径下,推荐用绝对路径或从 binary 同级目录开始写,例如config.NewFromYaml("./conf/machinery.yaml") -
broker和result_backend字段值必须带完整协议,redis://123456@localhost:6379✅,localhost:6379❌(machinery 不补协议) - 如果用 Redis,强烈建议补上
redis: pool_size: 20,默认池大小仅 5,高并发时任务排队明显 -
default_queue值不能含空格或斜杠,否则 AMQP 模式下直接报AMQP queue name invalid
怎么注册和发送一个带参数的异步任务
任务函数签名强制为 func(interface{}) error,多一个返回值、少一个 error、参数不是 interface{},都会在 server.RegisterTask 时 panic,错误提示只有模糊的 invalid task signature。
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
- 注册前先定义函数:
func sendEmail(payload interface{}) error { args := payload.(map[string]interface{}) to := args["to"].(string) // ... return nil }然后server.RegisterTask("send_email", sendEmail) - 发送时用
tasks.SendTaskWithContext,参数必须是 JSON 可序列化类型:string、int、map[string]interface{};struct{}要加json:tag,否则字段丢失 -
time.Time不能直传,会序列化失败,改用Unix()或Format("2006-01-02T15:04:05Z") - nil 切片传过去变成
null,worker 收到后得主动判空,别假设它还是[]string{}
延迟任务和重试为什么总不生效
延迟靠 ETA 字段(Unix 时间戳),不是“5秒后”,误写成 time.Now().Add(5 * time.Second).Unix() 看似对,但若系统时间不同步或 worker 时区错,就可能立刻执行或永远不触发;重试则完全依赖手动设 RetryCount 和 RetryTimeout,默认为 0,意味着哪怕 panic 也不会重试。
- 延迟任务必须用
&tasks.Signature{ETA: time.Now().Add(5 * time.Minute).Unix(), ...},别用Delay方法(v1 不支持) - 重试要显式写:
RetryCount: 3, RetryTimeout: 60,单位是秒;且注意:worker 重启后,未完成的重试次数会丢失——machinery 默认不持久化重试状态 - 重试期间若任务 panic,machinery 会按
RetryTimeout等待后重新入队,但不会保留原始 panic 堆栈,日志里只看到 “task failed”,得靠自己在函数里打全量 error 日志
最常被跳过的其实是配置校验环节:启动前打印一下 server.Config.Broker 和 server.Config.ResultBackend,确认它们非空;再检查 Redis 连接是否通、对应 DB 是否有权限——很多“没反应”的问题,根源只是 broker 地址写错了半字符。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










