Laravel 如何实现Job任务完成后向触发任务的用户发送通知
任务完成通知功能实现方案
核心架构逻辑
采用异步任务+事件驱动的解耦设计,既满足通用性,也不会引入过多复杂度,适配绝大多数中小规模业务场景,超大规模Job调度可在此基础上做组件升级。
1. 任务元数据绑定
- 所有用户触发生成的Job,必须在任务初始化阶段就将触发用户ID、通知渠道偏好、任务业务类型和Job ID做持久化绑定:
- 小流量场景直接在原有任务表新增字段即可:
trigger_user_id、notification_channel、notification_status(枚举值:pending/sent/failed) - 多业务线场景可以单独做任务通知关联表,和任务表做1:1关联
- 小流量场景直接在原有任务表新增字段即可:
- 存储选型无强制要求,关系型数据库(MySQL/PostgreSQL)、KV数据库(Redis)都可以,只要保证元数据不丢就行。
2. 任务状态变更事件触发
不要把通知逻辑硬编码在每个Job的业务实现中,会导致高度耦合,后续改通知规则需要修改所有任务代码,推荐用全局监听的方式统一触发:
- 主流任务调度框架基本都自带全局回调能力:
- Python Celery 用
after_return全局任务装饰器 - Java Quartz 用
JobListener监听任务执行结果 - Go Asynq/Sidekiq 用中间件拦截任务最终状态
- Python Celery 用
- 只要Job状态变更为执行成功/执行失败,就统一抛出
JobCompleted事件,事件仅需携带Job ID即可,不要冗余字段。
3. 通知消费处理
单独做无状态的通知消费者处理事件:
- 消费者拿到Job ID后先查询对应的任务元数据,获取用户ID和通知渠道,再调用对应渠道的发送接口(站内信、邮件、短信、APP推送等)
- 必须加重试机制:通知发送失败采用指数退避策略重试3次,重试仍然失败则将
notification_status标记为failed,后台保留手动补发入口即可,无需无限重试占用资源 - 加幂等校验:同一个Job ID的通知仅发送1次,避免事件重复消费导致用户重复收到提醒
- 注:通知逻辑必须完全异步,不要放在Job执行流程中同步处理,否则会拖慢任务执行效率,甚至导致Job超时失败。
4. 可选优化项
- 如需实时站内通知,可搭配WebSocket长连接,消费者发送通知的同时往对应用户的WebSocket通道推送消息,用户端无需刷新即可收到提醒
- 高并发场景下可将通知事件先写入消息队列(RabbitMQ/Kafka)做削峰,避免短时间大量任务跑完把通知服务打挂
- 可新增用户通知频次控制,避免短时间内同一个用户触发多个任务,收到过多骚扰提醒。
内容的提问来源于stack exchange,提问作者tews-nees
相关产品推荐
相关产品推荐

