You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何添加队列服务存储日志并在任务完成时向用户发送通知?

实现步骤指南

1. 梳理现有核心流程节点

先定位两个关键代码位置:

  • 任务触发入口:用户上传文件/点击按钮调用的接口,即当前返回{"action": "in progress"}的接口位置
  • 任务结束节点:不管是同步还是异步执行的任务,找到任务执行成功、执行失败的最终结束位置

2. 新建任务状态记录表(基于Postgresql)

新手优先用现有Postgresql实现存储,无需额外引入消息队列中间件,降低上手难度,表结构参考:

CREATE TABLE task_process_record (
    id BIGSERIAL PRIMARY KEY,
    task_unique_id VARCHAR(64) NOT NULL UNIQUE COMMENT '任务唯一标识',
    task_type VARCHAR(32) NOT NULL COMMENT '任务类型:文件上传/按钮触发对应业务',
    task_status VARCHAR(16) NOT NULL COMMENT '任务状态:IN_PROGRESS/SUCCESS/FAILED',
    start_time TIMESTAMP NOT NULL COMMENT '任务启动时间',
    end_time TIMESTAMP COMMENT '任务结束时间',
    cost_milliseconds BIGINT COMMENT '任务耗时,单位毫秒',
    trigger_user_id VARCHAR(64) COMMENT '触发任务的用户ID,用于定向通知',
    extra_info JSONB COMMENT '扩展字段,存储文件ID、请求参数等自定义内容',
    create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

3. 改造任务触发接口逻辑

修改现有触发接口的代码:

  • 任务启动时生成全局唯一taskId,可通过UUID.randomUUID().toString().replace("-","")生成
  • 向task_process_record插入一条初始化记录,task_status设为IN_PROGRESS,start_time设为当前时间,填充用户ID、任务类型等字段
  • 将原返回的{"action": "in progress"}调整为携带taskId:{"action": "in progress", "taskId": "生成的唯一ID"},返回给前端
  • 按原有逻辑触发业务任务执行,注意如果是异步任务,需要把生成的taskId传递到异步执行逻辑中

注意:如果任务是异步执行的,必须将taskId传递到异步任务的上下文里,否则后续更新任务状态时无法匹配到对应记录

4. 改造任务结束逻辑

在任务执行完成(含成功、失败)的位置新增逻辑:

  • 根据传入的taskId查询task_process_record对应的记录
  • 更新task_status为SUCCESS/FAILED,填入end_time为当前时间,计算耗时cost_milliseconds = end_time.getTime() - start_time.getTime()并存入表中
  • 新增通知逻辑:新手可先实现简单的前端轮询方案,新增一个查询接口,参数为taskId,返回任务状态、耗时、执行结果等信息;前端拿到IN_PROGRESS状态时每2-3秒轮询一次接口,拿到结束状态时直接弹窗提示用户即可,后续可升级为WebSocket实现实时推送

5. 可选升级:队列实现优化

如果后续任务量级提升,需要更规范的队列实现,可基于Spring生态扩展:

  • 单机场景:用Spring Event实现轻量级消息队列,无需额外中间件
  • 分布式场景:集成RabbitMQ/RocketMQ,将任务状态变更事件发送到队列中,消费端统一处理耗时统计、用户通知逻辑

内容的提问来源于stack exchange,提问作者Ritwik1711

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 00:54:03