背景
XXLJOB 2.1.0
需要升级到 2.3.1
版本
分析
版本差异
数据层面
- xxl_job_group 表
ALTER TABLE `xxl_job`.`xxl_job_group` DROP COLUMN `order`;
ALTER TABLE `xxl_job`.`xxl_job_group` MODIFY COLUMN `address_list` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '执行器地址列表,多地址逗号分隔' AFTER `address_type`;
ALTER TABLE `xxl_job`.`xxl_job_group` ADD COLUMN `update_time` datetime NULL DEFAULT NULL AFTER `address_list`;
- xxl_job_info表
ALTER TABLE `xxl_job`.`xxl_job_info` DROP COLUMN `job_cron`;
ALTER TABLE `xxl_job`.`xxl_job_info` ADD COLUMN `schedule_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'NONE' COMMENT '调度类型' AFTER `alarm_email`;
ALTER TABLE `xxl_job`.`xxl_job_info` ADD COLUMN `schedule_conf` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '调度配置,值含义取决于调度类型' AFTER `schedule_type`;
ALTER TABLE `xxl_job`.`xxl_job_info` ADD COLUMN `misfire_strategy` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'DO_NOTHING' COMMENT '调度过期策略' AFTER `schedule_conf`;
- xxl_job_log_report 表
ALTER TABLE `xxl_job`.`xxl_job_log_report` ADD COLUMN `update_time` datetime NULL DEFAULT NULL AFTER `fail_count`;
代码层面
增加了
com.xxl.job.core.handler.annotation.XxlJob
注解在使用的过程中通过标记方法来指定执行任务@XxlJob("demoJobHandler")
2.1.0
@Component @JobHandler("demoJobHandler") public class SampleXxlJob extends IJobHandler{ private static Logger logger = LoggerFactory.getLogger(SampleXxlJob.class); /** * 1、简单任务示例(Bean模式) */ public ReturnT<String> execute(String param) throws Exception { // default success return ReturnT.SUCCESS; } }
2.3.x
@Component public class SampleXxlJob { private static Logger logger = LoggerFactory.getLogger(SampleXxlJob.class); /** * 1、简单任务示例(Bean模式) */ @XxlJob("demoJobHandler") public void demoJobHandler() throws Exception { XxlJobHelper.log("XXL-JOB, Hello World."); for (int i = 0; i < 5; i++) { XxlJobHelper.log("beat at:" + i); TimeUnit.SECONDS.sleep(2); } // default success } }
删除了
com.xxl.job.core.handler.annotation.JobHandler
注解变动了
com.xxl.job.core.handler.IJobHandler
抽象类- 删除了常量结果
SUCCESS
FAIL
FAIL_TIMEOUT
- 变动了
execute
方法 ,把入参和出参全部删除掉了
- 删除了常量结果
增加了
com.xxl.job.core.context.XxlJobHelper
工具类- 通过该方法
getJobParam()
可以获取到任务执行时的参数 - 通过该方法
handleSuccess
设置执行后成功结果 - 通过该方法
handleFail
设置执行后失败结果
- 通过该方法
分析结果
所以结论项目中不能直接升级XXLJOB版本,会存在兼容方面的问题,直接升级会导致任务根本不能运行和编译不通过的问题。
所以解决方案有两个:
- 完全依照全新的方式调整业务定时任务
- 针对现有情况找到兼容的点即可实现
行动
接下来就按兼容的方案去针对该升级后版本如何能在尽少的情况下实现版本升级
数据方面
通过数据层面的差异执行相关脚本即可
代码方面
添加类
JobHandler
因为高版本对该了进行了删除,可通过拷贝低版本的,放在自定义包下即可@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Inherited public @interface JobHandler { String value() default ""; }
添加
JobHandlerSpringExecutor
该了为主要的核心类主要靠它做兼容,该类主要是通过继承了com.xxl.job.core.executor.impl.XxlJobSpringExecutor
@Slf4j public class JobHandlerSpringExecutor extends XxlJobSpringExecutor { @Override public void afterSingletonsInstantiated() { initJobHandlerRepository(getApplicationContext()); GlueFactory.refreshInstance(1); // super start try { super.start(); } catch (Exception e) { throw new RuntimeException(e); } } private void initJobHandlerRepository(ApplicationContext applicationContext) { if (applicationContext == null) { return; } // init job handler from method Map<String, Object> serviceBeanMap = applicationContext.getBeansWithAnnotation(JobHandler.class); if (serviceBeanMap.size() > 0) { for (Object serviceBean : serviceBeanMap.values()) { if (serviceBean instanceof IJobHandler) { String name = serviceBean.getClass().getAnnotation(JobHandler.class).value(); IJobHandler handler = (IJobHandler) serviceBean; if (loadJobHandler(name) != null) { throw new RuntimeException("xxl-job jobhandler[" + name + "] naming conflicts."); } registJobHandler(name, handler); } } } } }
调整原业务代码
com.xxl.job.core.handler.annotation.JobHandler
替换你新的包名xxx.JobHandler
获取参数
String param = XxlJobHelper.getJobParam();
处理结果也是用
com.xxl.job.core.context.XxlJobHelper
类
结果
使用兼容的方案不能完全的实现业务不该动的方案,所以下期针对XXLJOB 做一层适配,以免原框架改动而影响我们的业务,做一层适配的话,我们只需要在适配层做好这些兼容的处理即可不需要去改动业务。