注册任务函数必须使用签名 func(...interface{}) (interface{}, error) 的包级纯函数,返回 error 且不可用指针接收器;参数需支持 json 序列化,推荐基础类型。

怎么注册任务函数?必须返回 error 且不能用指针接收器
注册的任务函数必须满足签名 func(...interface{}) (interface{}, error),否则 RegisterTask 会静默失败或在运行时报 panic。常见错误是定义成 func(*MyStruct) error —— machinery 不支持方法绑定,只接受包级纯函数。
- ✅ 正确写法:
func Add(a, b int) (int, error) { return a + b, nil } - ❌ 错误写法:
func (s *Service) SendEmail() error { ... }(无法注册) - ⚠️ 注意:参数类型必须能被 JSON 序列化,
map[interface{}]interface{}或chan会 panic - ? 提示:建议统一用
int64/string等基础类型传参,避免结构体嵌套过深导致序列化失败
broker 和 result_backend 配置不匹配会卡住 worker 启动
worker 启动时不会校验 broker 连通性,但一旦开始消费,若 broker 地址错、认证失败或网络不通,日志里只会显示 "waiting for tasks...",没有任何报错——这是最常被忽略的“假死”现象。
- ✅ 启动前先手动测试连接:
redis-cli -u redis://localhost:6379 ping或curl -I amqp://guest:guest@localhost:5672 - ⚠️ 常见坑:
Broker用 Redis 时,ResultBackend不能也设成同一 Redis 实例的相同 DB(并发写冲突),建议分开 DB 或换用memcache - ? 配置项必须严格对应:
Broker是消息队列地址,ResultBackend是结果存储地址,二者不是同一个东西
SendTask 失败却不报错?检查 signature.Args 类型是否对齐
SendTask 返回 error 仅表示发送失败(如 broker 断连),但参数类型不匹配、任务未注册等逻辑错误,它默认静默丢弃——你发了任务,worker 却根本收不到。
- ✅ 正确构建参数:
Args: []tasks.Arg{{Type: "int", Value: 42}},Type必须是 Go 类型名字符串("string","float64"),不能写"[]byte"或自定义别名 - ⚠️ 常见错误:
Value: []int{1,2,3}→ 必须显式转为[]interface{},否则序列化失败且无提示 - ? 调试技巧:启动 worker 时加
-v参数(如果用了 logrus)或在worker.Start()前设置log.SetFlags(log.Lshortfile),看是否打印"task not registered"
并发数设太高反而拖慢?prefetch_count 和 concurrency 要配平
NewWorker(broker, backend, concurrency) 的 concurrency 控制 goroutine 数量,但真正限制吞吐的是 broker 层的 prefetch_count(AMQP)或 Redis 的 BRPOP 批量拉取行为。两者不协调会导致任务堆积或资源空转。
- ✅ 推荐比例:
concurrency = 2 × prefetch_count(例如 AMQP 的prefetch_count: 3→ workerconcurrency: 6) - ⚠️ 高并发陷阱:设
concurrency: 100但 Redis broker 没开连接池,瞬间打爆 Redis 连接数,报"dial tcp: too many open files" - ? 查看实际负载:用
redis-cli info clients | grep connected_clients或 RabbitMQ Management UI 观察 channel/queue 消费速率
Broker URL 少了个斜杠,或者 Add 函数忘了返回 error。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











