共计 1959 个字符,预计需要花费 5 分钟才能阅读完成。
背景与痛点
Cadence 是 Uber 开源的一款分布式工作流引擎,它解决了微服务架构下长时间运行流程的编排难题。在订单处理、数据流水线等场景中,Skill 调用(即 Activity 执行)是最核心的操作之一。新手常会遇到以下问题:

- 超时不可控:网络抖动导致 Activity 卡死,拖累整个工作流
- 重试风暴:因未设幂等键,失败重试引发数据重复处理
- 并发冲突:多个 Worker 同时处理同一 Activity 造成状态不一致
核心概念图解
先通过这张简化架构图理解组件关系:
graph LR
Client-->Workflow
Workflow-->|Schedule|Activity
Activity-->Worker
Worker-->|Respond|Workflow
关键组件定义:
- Workflow:持久化状态机,负责编排 Activity 调用顺序
- Activity(Skill):具体业务逻辑执行单元,如支付操作
- Worker:执行 Activity 的进程,可水平扩展
Go 代码实战
以下示例展示订单折扣计算场景:
// 1. 定义 Activity(Skill)type DiscountActivities struct{}
func (a *DiscountActivities) Calculate(ctx context.Context, orderID string) (float64, error) {
// 幂等性保障:相同 orderID 只处理一次
if isProcessed(orderID) {return 0, cadence.NewCanceledError("duplicate order")
}
// 模拟耗时操作
select {case <-time.After(30 * time.Second):
return applyDiscount(orderID)
case <-ctx.Done(): // 监听取消信号
return 0, ctx.Err()}
}
// 2. 注册 Worker
func startWorker() {
worker := worker.New(
serviceClient,
domain,
taskList,
worker.Options{ActivityPanicPolicy: worker.BlockWorkflow, // 熔断策略})
worker.RegisterActivity(&DiscountActivities{})
worker.Start()}
// 3. 工作流调用
func OrderWorkflow(ctx workflow.Context, orderID string) error {
ao := workflow.ActivityOptions{
ScheduleToStartTimeout: time.Minute,
StartToCloseTimeout: time.Minute * 5,
RetryPolicy: &cadence.RetryPolicy{
InitialInterval: time.Second,
BackoffCoefficient: 2,
MaximumInterval: time.Minute,
},
}
ctx = workflow.WithActivityOptions(ctx, ao)
var discount float64
err := workflow.ExecuteActivity(ctx, "Calculate", orderID).Get(&discount)
if err != nil {// 处理超时 / 重试逻辑}
return nil
}
生产环境要点
性能优化
- 预热 Worker 池:避免冷启动延迟,提前初始化 20% 的实例
- 批量处理 :对高频小任务使用
LocalActivity减少 RPC 开销
容错设计
- 断路器模式:当错误率超过阈值时,暂时跳过故障 Skill
- 死信队列:将反复失败的请求转入 DLQ 人工处理
五大避坑指南
- Signal 丢失 :务必设置
Workflow.GetSignalChannel()监听异步事件 - 超时连锁反应:父子工作流的超时应满足:子 < 父 /2
- 版本升级 :使用
workflow.GetVersion()管理向后兼容 - 日志追踪 :通过
workflow.GetLogger(ctx)输出带 WID 的日志 - 资源泄漏 :Activity 中必须处理
context.Done()信号
延伸思考
- 如何设计跨地域 Skill 调用?考虑用
Domain隔离 + 异步信号 - 能否实现动态 Skill 加载?研究
worker.RegisterActivityWithOptions - 大规模部署时,如何优化 TaskList 的分片策略?
通过这个完整示例,相信你已经掌握了 Cadence Skill 调用的核心要领。在实际项目中,建议从简单工作流开始,逐步增加重试、熔断等高级特性。遇到问题时,多利用 Cadence Web UI 观察工作流状态变化,这对调试非常有帮助。
正文完
发表至: 未分类
近一天内
