🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 一、概述 实际的业务中,我们会经常遇这样一种业务场景,它存在处理大量数据等耗时的任务,这些任务必须在某个时段范围或某些时段范围被处理,产生结果。从技术角度来看,这种场景如果直接在主业务程序中开发并部署,容易导致业务应用系统的耦合以及由于突发的大计算量导致的主业务运行不稳定。 基于这种技术和运维的考虑,基于技术平台,我们研发了自主的调度容器组件来解决这种应用需求。 ![](https://img.kancloud.cn/69/bd/69bd9e7f0b94abe6ca9c00589f45e644_1123x794.png) ## 二、技术特性 与主应用可分离独立运行; 技术平台所有基层设施可全面复用; 灵活的调度定制; 可在主应用中监控运行; 可靠的异常处理和干预机制; 与外部业务系统的集成能力; ## 三、开发教程 平台对调度服务的支持,提供了一套完整的运行体系;一般分成三层架构,包括job、manger和logic(考虑事务的灵活性,增加transactionalapi层); 调用关系如:Job--->Manager--->Logic--->transactionalapi; 开发工作,也就是针对上述逻辑代码及配置文件(一般复用业务的applicationContext-*.xml配置文件); 以下举例,从零开始,在既有项目中,开发一个job的完整过程; ### **job** ``` public class ComputeDynamicStoreJob extends UniframeworkTimerJob { @Override public void doBusinessLogic(JobExecution jobexecution) throws Exception { ComputeDynamicStoreLogic.execute((JobManager) getJobManager("noTransactionJobManager"), jobexecution); } @Override public long getDelayTime() { return MINUTE * 1; } @Override public long getPeriodTime() { return MINUTE * 2; } @Override public boolean multiInstanceEnabled() { return false; } @Override public boolean scheduleEnabled() { return true; } @Override public String desc() { return "计算动态库存"; } @Override public String allowedIps() { return null; } } ``` | 方法 | 用途 | 说明 | | --- | --- | --- | | doBusinessLogic| 核心业务逻辑 |这里是job中执行业务逻辑的代码入口| | getDelayTime | 设定执行延迟时间 |设定时间之后,调度才启动| | getPeriodTime| 设定执行间隔时间 |设定调度的间隔时间| | multiInstanceEnabled| 是否支持同时多个实例允许 |一般设置为false| | scheduleEnabled| 是否启用 |仅启用才会加载| | desc| 当前调度的描述信息 |描述信息 | | allowedIps| 设定允许执行当前调度的IP |如果当前仅部署在一台服务器,则可设置为null ### **logic/transactionalapi** 这里是业务的核心代码,含logic及transactionalapi; ComputeDynamicStoreLogic : ``` public class ComputeDynamicStoreLogic extends JobLogicSupport { public static void execute(JobManager manager, JobExecution jobexecution) throws Exception { ComputeDynamicStoreApi api = getJobLogicTransactionalApi("computeDynamicStoreApi"); api.doProcess(manager, material, jobexecution); } } ``` ComputeDynamicStoreApi : ``` public class ComputeDynamicStoreApi extends JobLogicTransactionalApi { public void doProcess(JobManager manager, DataMaterial material, JobExecution jobexecution) throws Exception { //真正核心的业务代码 } } ``` ### **manager** ``` public class JobManager extends JobManagerSupport { //定义项目级的JobManager } ``` 这个代码,在既有项目中,不需要再额外开发,全项目共享; ### **配置文件** 1、上述几个核心文件,transactionalapi必须配置到applicationContext-*.xml(可在项目工程中,任选一个一定被加载的applicationContext-*.xml文件)中,才能生效; 例如: ``` <bean id="computeDynamicStoreApi" parent="BaseServiceProxy"> <property name="target"> <bean class="com.erp.common.job.logic.transactionalapi.ComputeDynamicStoreApi"></bean> </property> </bean> ``` 2、为了jobserver能正常加载上述配置,需要将配置applicationContext-*.xml设置到uniframework.properties的server.jobserver.loadedctx,取名为仅仅取applicationContext-之后的名称,如:applicationContext-card.xml,则取名为card,如果有多个,则用|分开; 例如: ``` server.jobserver.loadedctx = card|nav ``` ### **打包部署** 到这里,一个完整的业务job,就全部开发完毕,打包部署,即可运行; >[danger] > 1、一般的,每个工程,都会有一个业务代码以及配置文件的jar包,比如,unerp4job.jar,包里面包含了工程所有的源码及配置文件; > 2、那么,在开发完毕,就把**所有**的工程文件重新打一个unerp4job.jar包,即可; > 3、将该包替换掉jobserver/lib中的同名文件,重启即可; > 更具体的信息参考:[调度服务器](../../%E4%BA%A7%E5%93%81%E5%AE%9E%E6%96%BD/%E7%B3%BB%E7%BB%9F%E5%8D%87%E7%BA%A7/%E8%B0%83%E5%BA%A6%E6%9C%8D%E5%8A%A1%E5%99%A8.md)