Uber Cadence工作流Pending Decision tasks未执行超时原因及排查
Uber Cadence集群Pending Decision Task未拾取触发超时问题排查
潜在触发原因
- Matching服务任务分发异常:Decision Task生成后会写入对应TaskList的分区,若Matching节点出现分区所有权漂移但未完成任务元数据同步,就会出现任务实际持久化在存储中、但没有节点负责向Worker派发的情况,这类状态同步问题默认不会打印error级日志,只有开启debug trace才能看到相关记录。
- Worker侧配置或注册异常:
- 所有监听目标TaskList的Worker要么只注册了Activity Worker没注册Decision Worker,要么把
MaxConcurrentDecisionTaskExecutionSize配置为0,这种情况集群侧能收到Worker的轮询请求,但判定没有可执行任务的Worker资源,会直接跳过派发,不会触发错误日志。 - Worker配置的Domain、TaskList名称、集群标识和工作流实际运行的配置不匹配,比如拼错TaskList名、用测试环境域名连生产集群,Worker实际在监听一个没有任务的空队列,目标TaskList完全没有有效消费者。
- 所有监听目标TaskList的Worker要么只注册了Activity Worker没注册Decision Worker,要么把
- 粘性调度链路异常:工作流默认开启粘性调度,Decision Task会优先派发到上一次处理过该工作流的Worker对应的专属粘性队列,如果对应Worker异常挂掉但集群没及时感知到节点下线,任务会一直卡在粘性队列直到粘性超时才会回退到公共TaskList;如果误将
StickyScheduleToStartTimeout改得比Decision Task整体超时时间还长,任务就会直接卡在粘性队列直到超时,根本不会走到公共派发流程。 - 集群限流规则拦截:如果对应Domain或者TaskList配置了并发任务限流,且配额被其他低优先级任务占满,Decision Task会一直在队列里排队,限流触发时默认只上报采样指标,不会打印全量错误日志,很容易出现“无报错但任务不跑”的情况。
- History服务事件同步异常:Decision Task派发依赖History服务生成完整的调度事件,如果History节点写入
DecisionTaskScheduled事件后出现Raft副本同步卡住、分片无主的情况,Matching服务拉不到可调度的任务元数据,任务会标记为Pending状态但根本进不了派发队列。
调试排查路径
- 第一步:核查工作流本身的任务属性
用Cadence CLI执行命令查询工作流详情:cadence --domain <业务域名> workflow describeid <workflowID> <runID>
重点看返回结果里的pendingDecision字段:- 如果
startedTime为空,说明任务从生成到超时从来没被Worker拾取过,直接排除Worker执行逻辑报错的可能 - 看
taskList字段值,如果是带Worker IP后缀的粘性队列,直接核查对应IP的Worker是否存活,同时核对Domain配置里的StickyScheduleToStartTimeout值,确认是否大于Decision超时时间 - 看
scheduledTimestamp计算实际排队时长,确认是不是从生成开始就一直没被派发
- 如果
- 第二步:核查TaskList对应的Matching服务监控
优先看三个核心指标,不用一开始就翻全量日志:- 若
matching_poll_success(轮询成功数)长期为0,说明根本没有Worker在监听这个TaskList,直接转向Worker侧配置排查 - 若
matching_throttled_task_count(限流拦截任务数)持续上涨,说明任务被限流规则拦截,直接核查Domain、TaskList级的并发配额配置是否设置过小 - 若
matching_task_dispatch_latency(任务派发延迟)p99远高于正常值,说明Matching节点对应分区负载过高或者所有权异常,手动触发分区主备切换即可恢复
- 若
- 第三步:Worker侧问题定位
- 先把Worker日志级别临时调到debug,查看轮询Decision Task的请求有没有收到非空响应,如果一直返回空,逐行核对Worker初始化时传入的Domain、TaskList、集群名参数,注意大小写、前后缀的拼写错误,这类拼写问题不会触发启动报错
- 检查Worker启动配置,确认
EnableDecisionWorker参数为true,ConcurrentDecisionTaskPollers、MaxConcurrentDecisionTaskExecutionSize两个核心并发参数没有被设为0 - 临时给Worker加配置
DisableStickyExecution: true关闭粘性调度做验证,如果关闭后新生成的Decision Task能被正常拾取,就能确定是粘性队列的节点状态同步问题
- 第四步:集群组件状态校验
- 核查对应工作流所在的History服务分片状态,确认分片Raft副本同步正常,没有主节点缺失、副本落后过多的情况
- 如果前面几步都没定位到问题,把Matching、History服务的日志级别临时调到debug,用WorkflowID搜索全链路日志,确认
DecisionTaskScheduled事件有没有正常生成、有没有成功推送到Matching组件,是否存在事件滞留在持久化层的情况
快速验证技巧:单独启动一个配置完全正确的测试Worker监听目标TaskList,如果测试Worker能正常拾取新生成的Decision Task,直接排除集群侧调度故障,问题一定出在原有Worker的配置或者运行状态上,无需再排查集群组件。
内容的提问来源于stack exchange,提问作者Ezio
相关产品推荐
相关产品推荐

