xxl-job源码改造集成:适配opengauss数据、适配单点登录等

目录

一、摘要

二、集成方案

三、集成步骤

3.1 springboot集成xxl-job

3.2 适配高斯数据库(postgresql)

3.3 页面集成

3.4 登录集成

3.5 接口集成

四、部署


一、摘要

        公司现在打算重构现有系统,将原来的quartz替换成xxl-job,主要因为quartz不能动态发布任务,而xxl-job开箱即用,还支持一系列新特性,有 动态编写任务、调度中心和执行器高可用(可集群部署)、任务路由策略多样、 弹性扩容、失败重试 等。

二、集成方案

        xxl-job架构分为管理端(调度中心)和客户端(各应用执行器),由调度中心调用各执行器执行任务,而且它有自己的用户和角色以及页面,目前只有mysql初始化脚本。因此原系统集成xxl-job,主要有以下几点需要集成:

        1、数据库集成:原系统是需要适配mysql和opengauss,因此xxl-job也需要适配opengauss,改造方案为:初始化脚本需要有opengauss版本的SQL、接口与后台任务运行的不兼容的SQL用改成兼容通用语法或修改逻辑用mybatis plus兼容,实在不行的则配置DatabaseIdProvider并用databaseId区分两种数据库的SQL,数据源配置统一改成公司的数据源配置。

        2、页面集成:由于xxl-job页面风格不一致、且页面不支持配置任务执行时间段,这里任务管理页面还是采用原公司任务管理页面,然后再开发个任务源码编辑查看页。任务管理页面的菜单和按钮权限还是和以前权限管理设置一样,不同的角色和用户设置不同的任务管理菜单和按钮。

        3、登录集成:由于原系统有自己的单点登录,因此需要将xxl-job的鉴权适配,改造方案为:登录拦截器改造,接口request里若没有符合单点登录的token则跳转公司登录页,若有token则给用户赋管理员权限。

        4、接口集成:调用quartz的接口全部改成调用xxl-job,任务运行的注解也改成xxl-job的注解。

三、集成步骤

3.1 springboot集成xxl-job

         这里先确定xxl-job的版本,看xxl-job在gitee和github的代码,人们对2.3.1的版本提的问题较少,且2.3.1也能满足需求,新特性都支持,这里选择2.3.1版本,然后下载下来。

   xxl-job源码改造集成:适配opengauss数据、适配单点登录等_第1张图片

        下载后,得到源码如下:

 xxl-job源码改造集成:适配opengauss数据、适配单点登录等_第2张图片

         可以看到,这里有三个模块:xxl-job-admin(调度中心)、xxl-job-core(执行器需添加的依赖)、xxl-job-executor-samples(执行器示例)。

        初始化数据库的SQL也有,具体如下:

xxl-job源码改造集成:适配opengauss数据、适配单点登录等_第3张图片

        找个mysql数据库运行下初始化脚本,然后改改xxl-job-admin里的配置(数据源、端口)再启动,访问管理页面,默认情况为 ip:8080/xxl-job-admin,首次登录会跳转登录页,用amdin/123456登录后可以看到类似如下首页:

xxl-job源码改造集成:适配opengauss数据、适配单点登录等_第4张图片

         执行器可以参考 xxl-job-executor-sample-springboot的示例来配置。主要是加入xxl-job-core依赖,声明好 ip、port、appname以及admin.addresses。注意的是,执行器的appname一定要在admin的执行器管理里进行添加,执行器才能连上admin(这个类似于先在调度中心申请一个凭证appname,后续执行器用凭证appname连上admin)。具体如下:

xxl-job源码改造集成:适配opengauss数据、适配单点登录等_第5张图片

xxl-job源码改造集成:适配opengauss数据、适配单点登录等_第6张图片         测试可行后,原定时任务在系统管理模块,因此,系统管理模块需加入xxl-job-core依赖并进行配置作为执行器、项目里需新建定时任务管理模块(存放xxl-job-admin代码)作为调度中心。

        具体目录结构如下:

xxl-job源码改造集成:适配opengauss数据、适配单点登录等_第7张图片

3.2 适配高斯数据库(postgresql)

        由于高斯数据库完全支持postgresql语法,所以根据xxl-job的mysql表结构编写pg的SQL,具体如下:

CREATE TABLE xxl_job_info (
  id serial constraint xxl_job_info_pkey primary key,
  job_group integer NOT NULL,
  job_desc varchar(255) NOT NULL,
  add_time timestamp DEFAULT NULL,
  update_time timestamp DEFAULT NULL,
  author varchar(64) DEFAULT NULL ,
  alarm_email varchar(255) DEFAULT NULL ,
  schedule_type varchar(50) NOT NULL DEFAULT 'NONE' ,
  schedule_conf varchar(128) DEFAULT NULL,
  misfire_strategy varchar(50) NOT NULL DEFAULT 'DO_NOTHING' ,
  executor_route_strategy varchar(50) DEFAULT NULL ,
  executor_handler varchar(255) DEFAULT NULL ,
  executor_param varchar(512) DEFAULT NULL ,
  executor_block_strategy varchar(50) DEFAULT NULL ,
  executor_timeout integer NOT NULL DEFAULT '0',
  executor_fail_retry_count integer NOT NULL DEFAULT '0' ,
  glue_type varchar(50) NOT NULL ,
  glue_source text ,
  glue_remark varchar(128) DEFAULT NULL ,
  glue_updatetime timestamp DEFAULT NULL ,
  child_jobid varchar(255) DEFAULT NULL ,
  trigger_status smallint NOT NULL DEFAULT '0' ,
  trigger_last_time bigint NOT NULL DEFAULT '0' ,
  trigger_next_time bigint NOT NULL DEFAULT '0'
);

comment on table xxl_job_info is '任务信息表';
comment on column xxl_job_info.id  is '主键';
comment on column xxl_job_info.job_group  is '执行器主键ID';
comment on column xxl_job_info.job_desc  is '任务描述';
comment on column xxl_job_info.add_time  is '任务创建时间';
comment on column xxl_job_info.update_time  is '任务更新时间';
comment on column xxl_job_info.author  is '作者';
comment on column xxl_job_info.alarm_email  is '报警邮件';
comment on column xxl_job_info.schedule_type  is '调度类型';
comment on column xxl_job_info.schedule_conf  is '调度配置,值含义取决于调度类型';
comment on column xxl_job_info.misfire_strategy  is '调度过期策略';
comment on column xxl_job_info.executor_route_strategy  is '执行器路由策略';
comment on column xxl_job_info.executor_handler  is '执行器任务handler';
comment on column xxl_job_info.executor_param is '执行器任务参数';
comment on column xxl_job_info.executor_block_strategy  is '阻塞处理策略';
comment on column xxl_job_info.executor_timeout  is '任务执行超时时间,单位秒';
comment on column xxl_job_info.executor_fail_retry_count  is '失败重试次数';
comment on column xxl_job_info.glue_type  is 'GLUE类型';
comment on column xxl_job_info.glue_source  is 'GLUE源代码';
comment on column xxl_job_info.glue_remark  is 'GLUE备注';
comment on column xxl_job_info.glue_updatetime  is 'GLUE更新时间';
comment on column xxl_job_info.child_jobid  is '子任务ID,多个逗号分隔';
comment on column xxl_job_info.trigger_status  is '调度状态:0-停止,1-运行';
comment on column xxl_job_info.trigger_last_time  is '上次调度时间';
comment on column xxl_job_info.trigger_next_time  is '下次调度时间';


CREATE TABLE xxl_job_log (
  id serial constraint xxl_job_log_pkey primary key,
  job_group integer NOT NULL,
  job_id integer NOT NULL,
  executor_address varchar(255) DEFAULT NULL,
  executor_handler varchar(255) DEFAULT NULL,
  executor_param varchar(512) DEFAULT NULL,
  executor_sharding_param varchar(20) DEFAULT NULL ,
  executor_fail_retry_count integer NOT NULL DEFAULT '0',
  trigger_time timestamp DEFAULT NULL,
  trigger_code integer NOT NULL,
  trigger_msg text,
  handle_time timestamp DEFAULT NULL,
  handle_code integer NOT NULL,
  handle_msg text ,
  alarm_status smallint NOT NULL DEFAULT '0'
) ;

CREATE INDEX I_trigger_time ON xxl_job_log (trigger_time);
CREATE INDEX I_handle_code ON xxl_job_log (handle_code);
comment on table xxl_job_log is '任务日志表';
comment on column xxl_job_log.id  is '主键';
comment on column xxl_job_log.job_group  is '执行器主键ID';
comment on column xxl_job_log.job_id  is '任务,主键ID';
comment on column xxl_job_log.executor_address  is '执行器地址,本次执行的地址';
comment on column xxl_job_log.executor_handler  is '执行器任务handler';
comment on column xxl_job_log.executor_param  is '执行器任务参数';
comment on column xxl_job_log.executor_sharding_param  is '执行器任务分片参数,格式如 1/2';
comment on column xxl_job_log.executor_fail_retry_count  is '失败重试次数';
comment on column xxl_job_log.trigger_time  is '调度-时间';
comment on column xxl_job_log.trigger_code  is '调度-结果';
comment on column xxl_job_log.trigger_msg  is '调度-日志';
comment on column xxl_job_log.handle_time  is '执行-时间';
comment on column xxl_job_log.handle_code  is '执行-状态';
comment on column xxl_job_log.handle_msg  is '执行-日志';
comment on column xxl_job_log.alarm_status  is '告警状态:0-默认、1-无需告警、2-告警成功、3-告警失败';


create or replace function upd_timestamp() returns trigger as
$$
begin
    new.update_time = current_timestamp;
    return new;
end
$$
    language plpgsql;


CREATE TABLE xxl_job_log_report (
  id serial constraint xxl_job_log_report_pkey primary key,
  trigger_day timestamp DEFAULT NULL,
  running_count integer NOT NULL DEFAULT '0',
  suc_count integer NOT NULL DEFAULT '0',
  fail_count integer NOT NULL DEFAULT '0',
  update_time timestamp DEFAULT NULL
);

CREATE UNIQUE INDEX i_trigger_day ON xxl_job_log_report (trigger_day);
comment on column  xxl_job_log_report.id  is '主键';
comment on column  xxl_job_log_report.trigger_day  is '调度-时间';
comment on column  xxl_job_log_report.running_count  is '运行中-日志数量';
comment on column  xxl_job_log_report.suc_count  is '执行成功-日志数量';
comment on column  xxl_job_log_report.fail_count  is '执行失败-日志数量';
comment on column  xxl_job_log_report.update_time  is '更新时间';


CREATE TABLE xxl_job_logglue (
  id serial constraint xxl_job_logglue_pkey primary key,
  job_id integer NOT NULL,
  glue_type varchar(50) DEFAULT NULL,
  glue_source text,
  glue_remark varchar(128) NOT NULL,
  add_time timestamp DEFAULT NULL,
  update_time timestamp DEFAULT NULL
);

create trigger t_xxl_job_logglue_update_time before update on xxl_job_logglue for each row execute procedure upd_timestamp();
comment on table xxl_job_logglue is '任务GLUE日志表';
comment on column xxl_job_logglue.id  is '主键';
comment on column xxl_job_logglue.job_id  is '任务,主键ID';
comment on column xxl_job_logglue.glue_type  is 'GLUE类型';
comment on column xxl_job_logglue.glue_source  is 'GLUE源代码';
comment on column xxl_job_logglue.glue_remark  is 'GLUE备注';
comment on column xxl_job_logglue.add_time  is '创建时间';
comment on column xxl_job_logglue.update_time  is '修改时间';

CREATE TABLE xxl_job_registry (
  id serial constraint xxl_job_registry_pkey primary key,
  registry_group varchar(50) NOT NULL,
  registry_key varchar(255) NOT NULL,
  registry_value varchar(255) NOT NULL,
  update_time timestamp DEFAULT NULL
);
CREATE INDEX i_g_k_v ON xxl_job_registry (registry_group,registry_key,registry_value);
comment on table xxl_job_registry is '任务注册表';
comment on column xxl_job_registry.id  is '主键';
comment on column xxl_job_registry.registry_group  is '注册分组';
comment on column xxl_job_registry.registry_key  is '注册键';
comment on column xxl_job_registry.registry_value  is '注册值';
comment on column xxl_job_registry.update_time  is '更新时间';


CREATE TABLE xxl_job_group (
  id serial constraint xxl_job_group_pkey primary key,
  app_name varchar(64) NOT NULL,
  title varchar(12) NOT NULL,
  address_type smallint NOT NULL DEFAULT '0',
  address_list text ,
  update_time timestamp DEFAULT NULL
);

comment on table xxl_job_group is '任务分组表';
comment on column xxl_job_group.id  is '主键';
comment on column xxl_job_group.app_name  is '执行器AppName';
comment on column xxl_job_group.title  is '执行器名称';
comment on column xxl_job_group.address_type  is '执行器地址类型:0=自动注册、1=手动录入';
comment on column xxl_job_group.address_list  is '执行器地址列表,多地址逗号分隔';


CREATE TABLE xxl_job_user (
  id serial constraint xxl_job_user_pkey primary key,
  username varchar(50) NOT NULL,
  password varchar(50) NOT NULL,
  role smallint NOT NULL,
  permission varchar(255) DEFAULT NULL
) ;


CREATE UNIQUE INDEX i_username ON xxl_job_user (username);
comment on table xxl_job_user is '任务用户表';
comment on column xxl_job_user.id  is '主键';
comment on column xxl_job_user.username  is '账号';
comment on column xxl_job_user.password  is '密码';
comment on column xxl_job_user.role  is '角色:0-普通用户、1-管理员';
comment on column xxl_job_user.permission  is '权限:执行器ID列表,多个逗号分割';


CREATE TABLE xxl_job_lock (
  lock_name varchar(50) NOT NULL,
  PRIMARY KEY (lock_name)
);

comment on table xxl_job_lock is '任务锁表';
comment on column xxl_job_lock.lock_name  is '锁名称';

INSERT INTO xxl_job_group( app_name, title, address_type, address_list, update_time) VALUES ('xxl-job-executor-sample', '示例执行器', 0, NULL, '2018-11-03 22:21:31' );
INSERT INTO xxl_job_info( job_group, job_desc, add_time, update_time, author, alarm_email, schedule_type, schedule_conf, misfire_strategy, executor_route_strategy, executor_handler, executor_param, executor_block_strategy, executor_timeout, executor_fail_retry_count, glue_type, glue_source, glue_remark, glue_updatetime, child_jobid) VALUES ( 1, '测试任务1', '2018-11-03 22:21:31', '2018-11-03 22:21:31', 'XXL', '', 'CRON', '0 0 0 * * ? *', 'DO_NOTHING', 'FIRST', 'demoJobHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2018-11-03 22:21:31', '');
INSERT INTO xxl_job_user( username, password, role, permission) VALUES ( 'admin', 'e10adc3949ba59abbe56e057f20f883e', 1, NULL);
INSERT INTO xxl_job_lock ( lock_name) VALUES ( 'schedule_lock');

        接着xml文件里将“`”去除,具体如下:

xxl-job源码改造集成:适配opengauss数据、适配单点登录等_第8张图片

        调整findDead逻辑,原SQL( DATE_ADD(#{nowTime},INTERVAL -#{timeout} SECOND))不兼容pg语法, 如下:

xxl-job源码改造集成:适配opengauss数据、适配单点登录等_第9张图片

        这句SQL是找出更新时间小于(当前时间-配置的超时时间)的注册组,查了下网上写法,都不怎么好,这里改用集成mybatis plus,用mybatis plus来进行查询。具体如下:

xxl-job源码改造集成:适配opengauss数据、适配单点登录等_第10张图片

        另外,使用了mybatis plus,有些表会发生主键插入异常,具体解决办法如下:

xxl-job源码改造集成:适配opengauss数据、适配单点登录等_第11张图片

        调整不等于判断,具体如下:

xxl-job源码改造集成:适配opengauss数据、适配单点登录等_第12张图片

         将驼峰改成小写适配高斯数据库

         基本就以上这些了,连接pg数据库也能正常运行admin并新增执行器和任务运行,并能看到日志以及统计。

3.3 页面集成

        页面集成意味着客户无法看到admin管理页,只能看到原来的任务页,原页面如下:

xxl-job源码改造集成:适配opengauss数据、适配单点登录等_第13张图片

        目前页面保持不变,页面的对应的菜单和按钮权限都不变,接口的url以及参数和返回值都不变,xxl-job-admin的管理页对用户不可见,我这里修改路径和端口,并不暴露给前端和nginx。由于管理页不可见,需要把新增执行器appname的sql写在初始化SQL里。

3.4 登录集成

        这里调整拦截器PermissionInterceptor和toLogin处理即可。具体如下:

xxl-job源码改造集成:适配opengauss数据、适配单点登录等_第14张图片

         这里PermissionInterceptor拦截器去除needAdminUser判断,直接从request里获取token,获取不到或根据token查不到登录用户信息,则跳转toLogin,若能获取到用户登录信息,则给用户赋值xxl-job的管理员权限并保存到request的属性中即可。

xxl-job源码改造集成:适配opengauss数据、适配单点登录等_第15张图片

         这里toLogin处理直接重定向公司的单点登录地址即可。

3.5 接口集成

        这里系统管理模块里原来任务controller保持不变,服务层原来调用quartz的逻辑全部换成xxl-job。具体如下:

xxl-job源码改造集成:适配opengauss数据、适配单点登录等_第16张图片

         系统管理模块(执行器)保存时调用feign接口,进而调用xxl-job-admin的新增方法。这里通过任务参数关联系统管理的任务,后续执行器执行任务时,可以通过任务参数找到添加的任务配置,进而进行相应处理。任务注解就简单了,换用@XxlJob注解即可。剩下的任务业务逻辑各自按业务进行调整。

四、部署

        这里考虑高可用,所以系统管理模块(执行器)和任务管理模块(调度中心xxl-job-admin)都是集群部署。这里部署需要注意,所有机器的时间必须保持一致。调度中心连接同一个数据库多实例启动即可,执行器配在admin.address配置各调度中心的地址后多实例启动即可。

      


 

你可能感兴趣的:(定时任务,xxl-job,springboot,postgresql,集成,登录,集成)