基于 Spring 打造简单高效通用的异步任务处理系统
背景
随着应用系统功能的不断新增,而某些功能的实现对实时性要求并不是那么高,但是逻辑却很复杂、执行比较耗时
比如涉及外部系统调用、多数据源等等;此时,我们就希望可以让这些复杂的业务逻辑放在后台执行,而前台与用
户的交互可以不用等待,从而提高用户体验;
另外,从系统架构这个层面来说,我们也希望按照不同功能来拆分,以保持各个系统之间的低耦合,当一个系统出
现问题时不会影响到其他系统,并且对于独立的各个系统,我们可以专门进行性能优化、监控等;所以我们需要通
用、高效的异步任务处理系统;
设计目标
打造轻量级、简单、高效、通用、高扩展性、高可靠性的异步任务处理系统!
系统设计
要实现类似的异步处理系统,相信大家首先想到的就是 JMS,Alibaba 里面也有基于 JMS 的异步处理系统,而且该
系统在网店系统中应用非常广泛;但由于目前我们阿里软件采用了不同的技术框架,所以不能直接拿来使用;况且
该系统为了实现异步任务系统的并发,采取了 JMS 与 MDB 结合的策略,所以系统就依赖于 EJB 了,这样系统就变
得笨重了,由此系统部署的应用服务器必须要支持 EJB,一些轻量级的不支持 EJB 规范的应用服务器就没法部署了;
考虑到如上的系统设计目标,我们的设计思路为:任务 DB 持久化 + Spring 封装 Job 调度、线程池;
l 任务 DB 持久化:是说我们需要将待处理的任务信息保存在我们可信任的 DB 中,若任务未到达千万级可以和业务
DB 放在一起,确保当我们的任务处理服务器 down 了之后这些未执行成功、或未开始执行的任务不会被丢失;
l Spring 封装 Job 调度:当任务信息都持久化在 DB 中之后,我们需要将这些信息读取出来执行具体的业务逻辑操作,
这里我们通过 ScheduledExecutorFactoryBean 来实现对任务的循环调度,比如说可采取每隔 5min 扫描一次待处理任
务列表,若有记录则提取出来执行;当然,若要实现更加强大的任务调度功能,可以采用 Spring 内部集成的 Quartz
这个开源调度框架;
l Spring 封装线程池:为了提高任务执行效率,我们必须考虑让任务的具体操作能够被并发执行;为了让系统更加
轻量级,这里我们直接采用 Spring 中基于 JDK 线程池的默认封装实现,通过配置调整参数;
系统的部署图可参考下图:
下
面
我
们
来
看
以
下
具
体
的
系
统
设
计:
首
先
需
要
新