出了问题看哪里

出问题时该看哪里,以及 gotick 在 Redis 里留下了什么。

本页目录

检查界面

内置一个网页界面,能看到:哪些调用在跑、每一个停在哪一步、各步花了多久、错在哪里、还要睡多久。它就是一个普通的 http.Handler,直接读 Redis,不需要连上正在跑的 worker。它在独立子包里,不 import 它的人二进制一个字节都不会涨。它能看到你传进去的所有 metadata,所以前面务必加鉴权。

01挂到你的 mux 上

折进一个你已经在发布的服务里,鉴权中间件也直接复用现成的。工作量最小。

h, _ := ui.NewHandler(ui.Options{ RootPath: "/_gotick", Store: store.NewRedisStore(rdb), Auth: myAuthMiddleware,})mux.Handle("/_gotick/", h)
02给它一个独立端口

适合本身没有 HTTP 服务的进程,用法类比 net/http/pprof。没给凭据就想绑非回环地址,会被直接拒绝,不是只警告一句。

go ui.ListenAndServe("127.0.0.1:6060", ui.Options{ Store: store.NewRedisStore(rdb),})
03从终端看一眼

线上不对劲:不改代码、不发版,把命令行指向 Redis 就能看现场。

go run github.com/zbysir/gotick/cmd/gotick@latest ui \ -redis redis://localhost:6379/0

命令行

gotick inspect 打印一次调用的所有步骤和 metadata:状态、重试次数、下次执行时刻、最后一次的错误。它同样只读 Redis,卡住的流程不必碰正在运行的服务就能诊断。想把界面当独立服务跑,也有现成的容器镜像。

$ gotick inspect -redis redis://localhost:6379/0 9f2ac41b8e7d callId  9f2ac41b8e7dtasks   3 TASK        STATUS  RETRY  RUN AT                LAST ERRORsend-email  retry   1      2026-08-18T09:12:06Z  smtp timeoutstart       done    0      -                     -wait        sleep   0      2026-08-18T09:12:03Z  - metadata  order_id = ORD-1

存了什么,存多久

全都在你指给 gotick 的那个 Redis 里。清理是自动的,下面这些是默认值。

里面是什么保留多久
<callId>_status每个步骤一个字段:状态、重试次数、耗时、最后一次错误调用进终态之后 7 天
<callId>_meta你传的 metadata、Memo 的结果、已投递的信号调用进终态之后 7 天
gotick:run:<callId>界面列表里那条运行摘要7 天 TTL
gotick:runs、gotick:flow:<id>:runs按开始时间索引运行记录的有序集合超过保留期的会被裁掉,最多每 10 分钟裁一次
gotick:flows跑过的 flow id 列表不清理,大小取决于你有多少 flow
gotick:keys:<flowId>业务 key 到 callId 的映射,每个 flow 一张哈希表对应的调用一结束就删掉那一条
asynq:*asynq 自己的队列和统计成功的任务不保留;重试耗尽的归档 90 天

配置项

字段作用
RedisURL / RedisClientRedis 在哪。传自己的 client 可以复用已有的连接池。
Queue队列命名空间,默认 gotick。要把一组流程和另一组隔开就改这里。
Concurrency一个 worker 同时执行多少个任务,默认 10。
DelayedTaskCheckInterval已排期的任务多久被搬到待执行,也就是每个 Sleep、每次重试退避的实际精度,默认 500 毫秒。调大省 Redis 轮询,代价是醒得没那么准。
TaskCheckInterval队列空的时候多久查一次新任务,默认 100 毫秒。
ConsumeLegacyPerFlowQueues从旧的「一个 flow 一个队列」升级时打开,让 worker 额外消费旧队列,排空之后再关掉。

Render diagnostics