异步队列任务的go语言处理器函数

函数签名

func HandleCreateJobTask(ctx context.Context, task *asynq.Task) error
  • 功能:处理来自异步队列的创建作业任务
  • 输入
    • ctx context.Context:携带链路跟踪信息的上下文
    • task *asynq.Task:异步任务对象(使用asynq库)
  • 输出:错误信息(决定任务是否需要重试)

核心处理流程

Consumer DB K8s 1.开启事务,锁定任务记录 2.查询主任务信息 3.查询子任务列表 4.验证任务状态 5.补全存储配置 6.生成作业资源描述 7.创建K8s资源 8.提交事务 Consumer DB K8s

关键代码解析

1. 上下文与载荷解析
ctx = NewTaskContext(ctx, task.Type()) // 创建任务类型上下文
payload := &CreateJobPayload{}
err := json.Unmarshal(task.Payload(), payload) // 解析任务载荷
  • NewTaskContext:扩展上下文,添加任务类型标记(用于日志跟踪)
  • Payload解析:将异步任务携带的JSON数据反序列化为结构体
2. 数据库事务
err = dao.TaskDao.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
    // 事务操作
})
  • 事务范围:包裹所有数据库操作,保障原子性
  • LockUpdate():使用SELECT ... FOR UPDATE锁定记录,防止并发修改
3. 主任务校验
one, err := dao.TaskDao.Ctx(ctx).LockUpdate().
    Where(columns.TaskId, payload.TaskId).
    Where(columns.Status, types.DataStatusActive).One()
  • 双重校验
    1. 检查任务是否存在(one.IsEmpty()
    2. 检查任务状态是否允许操作(util.ArrayContains校验非法状态)
4. 存储配置补全
err = FillStorageInfo(ctx, taskInfo) // 补充存储详细信息
  • 业务需求:主任务仅存储存储标识,需要补全完整存储配置
  • 潜在实现:可能查询存储服务或配置中心获取详细信息
5. 子任务处理
all, err := dao.SubTaskDao.Ctx(ctx).
    Where(columns.TaskId, payload.TaskId).
    Where(columns.Status, types.DataStatusActive).All()
  • 关联查询:获取所有有效的子任务记录
  • 空值检查all.IsEmpty()确保至少存在一个子任务
6. 作业工厂模式
jobFactory, err := job.NewJobFactory(taskInfo, subTasks)
err = jobFactory.Validate(ctx)       // 参数校验
resources, err := jobFactory.GenerateResources(ctx) // 生成K8s资源
  • 工厂模式:隔离资源生成逻辑
  • 生成内容:可能包含Deployment/Job/Service等K8s资源描述
7. 资源提交
err = createJobResource(ctx, taskInfo.ClusterId, resources)
  • 集群操作:根据任务指定的集群ID(ClusterId)提交资源
  • 潜在实现:使用Kubernetes client-go库与指定集群API交互

事务管理策略

操作阶段是否影响事务说明
数据库查询✅ 是使用事务上下文执行
外部存储查询❌ 否FillStorageInfo可能涉及外部调用
K8s资源创建❌ 否发生在事务提交前

关键注意点
K8s资源创建操作不在事务保护范围内,可能造成:

  1. 数据库事务提交失败但资源已创建 → 需要补偿机制
  2. 资源创建失败但事务已提交 → 需任务重试机制

错误处理设计

错误分类
错误类型处理方式重试策略
数据校验失败(如非法状态)记录警告日志,返回错误不重试
数据库连接失败记录错误日志,返回错误自动重试
K8s API调用失败记录错误日志,返回错误自动重试
重试机制
  • asynq特性:默认自动重试(指数退避)
  • 幂等设计
    • 通过LockUpdate防止并发修改
    • 资源创建需支持幂等(如检查资源已存在)

潜在改进建议

  1. 补偿事务设计
// 在事务提交后添加后续操作
tx.AfterCommit(func() {
    if err := createJobResource(...); err != nil {
        // 启动补偿任务回滚数据库
    }
})
  1. 增加 tracing
// 添加分布式追踪
span, ctx := opentracing.StartSpanFromContext(ctx, "create_job")
defer span.Finish()
  1. 资源预检
// 提交前检查集群可用性
if err := checkClusterHealth(taskInfo.ClusterId); err != nil {
    return fmt.Errorf("cluster unavailable: %v", err)
}

典型执行场景

// 任务入队示例
client.Enqueue(asynq.NewTask("create_job", payload))

// 工作流示意图
TaskCreated → 消息入队 → 消费者处理 → 数据库操作 → K8s资源创建
                    ^                 |
                    |-----------------|
                         重试机制

这个实现展示了典型的任务队列处理模式,结合数据库事务与外部系统操作,需要注意分布式场景下的数据一致性保障。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值