异步任务
异步任务用于把耗时操作从当前请求线程中拆出去执行,例如通知发送、文件处理、统计计算等。RuoYi Office 框架侧在 yudao-spring-boot-starter-job 中启用了 Spring @Async,并通过 YudaoAsyncAutoConfiguration 为 ThreadPoolTaskExecutor 和 SimpleAsyncTaskExecutor 注入 TTL 任务装饰器,确保上下文在线程切换时传递。
框架实现要点
| 能力 | 实现位置 | 说明 |
|---|---|---|
| 开启异步 | YudaoAsyncAutoConfiguration | 使用 @EnableAsync |
| 线程池上下文传递 | TtlRunnable::get | 处理租户、登录态、链路上下文等 ThreadLocal 传递 |
| 线程池类型 | ThreadPoolTaskExecutor、SimpleAsyncTaskExecutor | 初始化前统一设置 TaskDecorator |
使用建议
- 异步方法保持幂等:请求超时、服务重启或手动重试时,异步逻辑不要重复产生副作用。
- 不要依赖事务未提交数据:如果异步任务读取当前事务写入的数据,优先在事务提交后触发。
- 明确异常处理:异步方法异常不会直接返回给前端,应记录日志或写入业务状态。
- 线程池容量要可控:大量文件、通知、AI 任务不要共用过小的默认线程池。
与定时任务的区别
| 类型 | 适合场景 | 触发方式 |
|---|---|---|
| 异步任务 | 当前请求派生出的后台处理 | 业务代码主动调用 |
| 定时任务 | 固定周期巡检、同步、补偿 | Cron 调度或手动触发 |
| 消息队列 | 跨服务解耦、削峰、可靠投递 | 发布/消费消息 |
排查清单
| 现象 | 优先检查 |
|---|---|
| 异步中拿不到租户/用户 | 是否经过框架线程池;是否被自定义线程绕过 TTL 装饰器 |
| 异步异常无感知 | 是否配置异常日志;业务状态是否回写 |
| 请求结束但任务没执行 | 方法是否被 Spring 代理调用;是否同类内部直接调用 @Async 方法 |
| 线程池耗尽 | 任务耗时、队列长度、线程池配置、是否需要拆分专用线程池 |
