编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

XXL-JOB适配达梦数据库

wxchong 2024-06-11 09:58:44 开源技术 17 ℃ 0 评论

#挑战30天在头条写日记#

#关于知识产权必须知道的那些事#
一、什么是XXL-JOB

xxl-job是一个分布式的任务调度平台,其核心设计目标是:学习简单、开发迅速、轻量级、易扩展,现在已经开放源代码并接入多家公司的线上产品线,开箱即用。xxl是xxl-job的开发者大众点评的许雪里名称的拼音开头。

xxl-job框架主要用于处理分布式的定时任务,其主要由调度中心和执行器组成。

调度模块(调度中心):

负责管理调度信息,按照调度配置发出调度请求,自身不承担业务代码。调度系统与任务解耦,提高了系统可用性和稳定性,同时调度系统性能不再受限于任务模块;

支持可视化、简单且动态的管理调度信息,包括任务新建,更新,删除,GLUE开发和任务报警等,所有上述操作都会实时生效,同时支持监控调度结果以及执行日志,支持执行器Failover。

执行模块(执行器):

负责接收调度请求并执行任务逻辑。任务模块专注于任务的执行等操作,开发和维护更加简单和高效;

接收“调度中心”的执行请求、终止请求和日志请求等。

总结:

调度中心:统一管理任务调度平台上的调度任务,负责触发调度执行,并且提供任务管理平台。

? 执行器:接收调度中心的调度并且执行,可以直接执行也可以集成到项目中。

? 调度中心和执行器两个模块分开部署,相互分离,两者之间通过RPC进行通信,其中调度中心主要是提供一个平台,管理调度信息,发送调度请求,自己不承担业务代码,而执行器接受调度中心的调度执行业务逻辑。

二、修改xxl-job的sql

官方中版本的升级,将旧版本中的JOB_CRON替换为SCHEDULE_CONF、MISFIRE_STRATEGY进行搭配使用

CREATE TABLE "SYSDBA"."XXL_JOB_GROUP"
(
    "ID" INT IDENTITY(1, 1) NOT NULL,
    "APP_NAME" VARCHAR(64) NOT NULL,
    "TITLE" VARCHAR(64) NOT NULL,
    "ADDRESS_TYPE" TINYINT DEFAULT 0 NOT NULL,
    "ADDRESS_LIST" VARCHAR(512),
    "UPDATE_TIME" DATETIME(6),
    NOT CLUSTER PRIMARY KEY("ID")) STORAGE(ON "MAIN", CLUSTERBTR) ;

CREATE TABLE "SYSDBA"."XXL_JOB_INFO"
(
    "ID" INT IDENTITY(1, 1) NOT NULL,
    "JOB_GROUP" INT NOT NULL,
    "SCHEDULE_CONF" VARCHAR(128) NOT NULL,
    "JOB_DESC" VARCHAR(255) NOT NULL,
    "ADD_TIME" TIMESTAMP(0),
    "UPDATE_TIME" TIMESTAMP(0),
    "AUTHOR" VARCHAR(64),
    "ALARM_EMAIL" VARCHAR(255),
    "EXECUTOR_ROUTE_STRATEGY" VARCHAR(50),
    "EXECUTOR_HANDLER" VARCHAR(255),
    "EXECUTOR_PARAM" VARCHAR(512),
    "EXECUTOR_BLOCK_STRATEGY" VARCHAR(50),
    "EXECUTOR_TIMEOUT" INT DEFAULT 0 NOT NULL,
    "EXECUTOR_FAIL_RETRY_COUNT" INT DEFAULT 0 NOT NULL,
    "GLUE_TYPE" VARCHAR(50) NOT NULL,
    "GLUE_SOURCE" CLOB,
    "GLUE_REMARK" VARCHAR(128),
    "GLUE_UPDATETIME" TIMESTAMP(0),
    "CHILD_JOBID" VARCHAR(255),
    "TRIGGER_STATUS" TINYINT DEFAULT 0 NOT NULL,
    "TRIGGER_LAST_TIME" BIGINT DEFAULT 0 NOT NULL,
    "TRIGGER_NEXT_TIME" BIGINT DEFAULT 0 NOT NULL,
    "MISFIRE_STRATEGY" VARCHAR(50) DEFAULT 'DO_NOTHING',
    "SCHEDULE_TYPE" VARCHAR(50) DEFAULT 'NONE',
    NOT CLUSTER PRIMARY KEY("ID")) STORAGE(ON "MAIN", CLUSTERBTR) ;

COMMENT ON COLUMN "SYSDBA"."XXL_JOB_INFO"."ALARM_EMAIL" IS '报警邮件';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_INFO"."AUTHOR" IS '作者';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_INFO"."CHILD_JOBID" IS '子任务ID,多个逗号分隔';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_INFO"."EXECUTOR_BLOCK_STRATEGY" IS '阻塞处理策略';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_INFO"."EXECUTOR_FAIL_RETRY_COUNT" IS '失败重试次数';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_INFO"."EXECUTOR_HANDLER" IS '执行器任务handler';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_INFO"."EXECUTOR_PARAM" IS '执行器任务参数';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_INFO"."EXECUTOR_ROUTE_STRATEGY" IS '执行器路由策略';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_INFO"."EXECUTOR_TIMEOUT" IS '任务执行超时时间,单位秒';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_INFO"."GLUE_REMARK" IS 'GLUE备注';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_INFO"."GLUE_SOURCE" IS 'GLUE源代码';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_INFO"."GLUE_TYPE" IS 'GLUE类型';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_INFO"."GLUE_UPDATETIME" IS 'GLUE更新时间';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_INFO"."JOB_GROUP" IS '执行器主键ID';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_INFO"."MISFIRE_STRATEGY" IS '调度过期策略';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_INFO"."SCHEDULE_CONF" IS '调度配置,值含义取决于调度类型';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_INFO"."SCHEDULE_TYPE" IS '调度类型';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_INFO"."TRIGGER_LAST_TIME" IS '上次调度时间';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_INFO"."TRIGGER_NEXT_TIME" IS '下次调度时间';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_INFO"."TRIGGER_STATUS" IS '调度状态:0-停止,1-运行';
CREATE UNIQUE  INDEX "INDEX1270631958585700" ON "SYSDBA"."XXL_JOB_INFO"("ID" ASC) STORAGE(ON "MAIN", CLUSTERBTR) ;


CREATE TABLE "SYSDBA"."XXL_JOB_LOCK"
(
    "LOCK_NAME" VARCHAR(50) NOT NULL,
    NOT CLUSTER PRIMARY KEY("LOCK_NAME")) STORAGE(ON "MAIN", CLUSTERBTR) ;

COMMENT ON COLUMN "SYSDBA"."XXL_JOB_LOCK"."LOCK_NAME" IS '锁名称';
CREATE UNIQUE  INDEX "INDEX1270631953400600" ON "SYSDBA"."XXL_JOB_LOCK"("LOCK_NAME" ASC) STORAGE(ON "MAIN", CLUSTERBTR) ;

CREATE TABLE "SYSDBA"."XXL_JOB_LOG"
(
    "ID" BIGINT IDENTITY(1, 1) NOT NULL,
    "JOB_GROUP" INT NOT NULL,
    "JOB_ID" INT NOT NULL,
    "EXECUTOR_ADDRESS" VARCHAR(255),
    "EXECUTOR_HANDLER" VARCHAR(255),
    "EXECUTOR_PARAM" VARCHAR(512),
    "EXECUTOR_SHARDING_PARAM" VARCHAR(20),
    "EXECUTOR_FAIL_RETRY_COUNT" INT DEFAULT 0 NOT NULL,
    "TRIGGER_TIME" TIMESTAMP(0),
    "TRIGGER_CODE" INT NOT NULL,
    "TRIGGER_MSG" TEXT,
    "HANDLE_TIME" TIMESTAMP(0),
    "HANDLE_CODE" INT NOT NULL,
    "HANDLE_MSG" TEXT,
    "ALARM_STATUS" TINYINT DEFAULT 0 NOT NULL,
    NOT CLUSTER PRIMARY KEY("ID")) STORAGE(ON "MAIN", CLUSTERBTR) ;

COMMENT ON COLUMN "SYSDBA"."XXL_JOB_LOG"."ALARM_STATUS" IS '告警状态:0-默认、1-无需告警、2-告警成功、3-告警失败';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_LOG"."EXECUTOR_ADDRESS" IS '执行器地址,本次执行的地址';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_LOG"."EXECUTOR_FAIL_RETRY_COUNT" IS '失败重试次数';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_LOG"."EXECUTOR_HANDLER" IS '执行器任务handler';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_LOG"."EXECUTOR_PARAM" IS '执行器任务参数';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_LOG"."EXECUTOR_SHARDING_PARAM" IS '执行器任务分片参数,格式如 1/2';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_LOG"."HANDLE_CODE" IS '执行-状态';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_LOG"."HANDLE_MSG" IS '执行-日志';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_LOG"."HANDLE_TIME" IS '执行-时间';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_LOG"."JOB_GROUP" IS '执行器主键ID';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_LOG"."JOB_ID" IS '任务,主键ID';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_LOG"."TRIGGER_CODE" IS '调度-结果';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_LOG"."TRIGGER_MSG" IS '调度-日志';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_LOG"."TRIGGER_TIME" IS '调度-时间';


CREATE  INDEX "I_HANDLE_CODE" ON "SYSDBA"."XXL_JOB_LOG"("HANDLE_CODE" ASC) STORAGE(ON "MAIN", CLUSTERBTR) ;
CREATE  INDEX "I_TRIGGER_TIME" ON "SYSDBA"."XXL_JOB_LOG"("TRIGGER_TIME" ASC) STORAGE(ON "MAIN", CLUSTERBTR) ;
CREATE UNIQUE  INDEX "INDEX1270631927335900" ON "SYSDBA"."XXL_JOB_LOG"("ID" ASC) STORAGE(ON "MAIN", CLUSTERBTR) ;

CREATE TABLE "SYSDBA"."XXL_JOB_LOGGLUE"
(
    "ID" INT IDENTITY(1, 1) NOT NULL,
    "JOB_ID" INT NOT NULL,
    "GLUE_TYPE" VARCHAR(50),
    "GLUE_SOURCE" CLOB,
    "GLUE_REMARK" VARCHAR(128) NOT NULL,
    "ADD_TIME" TIMESTAMP(0),
    "UPDATE_TIME" TIMESTAMP(0),
    NOT CLUSTER PRIMARY KEY("ID")) STORAGE(ON "MAIN", CLUSTERBTR) ;

COMMENT ON COLUMN "SYSDBA"."XXL_JOB_LOGGLUE"."GLUE_REMARK" IS 'GLUE备注';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_LOGGLUE"."GLUE_SOURCE" IS 'GLUE源代码';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_LOGGLUE"."GLUE_TYPE" IS 'GLUE类型';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_LOGGLUE"."JOB_ID" IS '任务,主键ID';
CREATE UNIQUE  INDEX "INDEX1270631899079200" ON "SYSDBA"."XXL_JOB_LOGGLUE"("ID" ASC) STORAGE(ON "MAIN", CLUSTERBTR) ;

CREATE TABLE "SYSDBA"."XXL_JOB_LOG_REPORT"
(
    "ID" INT IDENTITY(1, 1) NOT NULL,
    "TRIGGER_DAY" TIMESTAMP(0),
    "RUNNING_COUNT" INT DEFAULT 0 NOT NULL,
    "SUC_COUNT" INT DEFAULT 0 NOT NULL,
    "FAIL_COUNT" INT DEFAULT 0 NOT NULL,
    NOT CLUSTER PRIMARY KEY("ID"),
    CONSTRAINT "I_TRIGGER_DAY" UNIQUE("TRIGGER_DAY")) STORAGE(ON "MAIN", CLUSTERBTR) ;

COMMENT ON COLUMN "SYSDBA"."XXL_JOB_LOG_REPORT"."FAIL_COUNT" IS '执行失败-日志数量';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_LOG_REPORT"."RUNNING_COUNT" IS '运行中-日志数量';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_LOG_REPORT"."SUC_COUNT" IS '执行成功-日志数量';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_LOG_REPORT"."TRIGGER_DAY" IS '调度-时间';
CREATE UNIQUE  INDEX "INDEX1270631909054600" ON "SYSDBA"."XXL_JOB_LOG_REPORT"("ID" ASC) STORAGE(ON "MAIN", CLUSTERBTR) ;

CREATE TABLE "SYSDBA"."XXL_JOB_REGISTRY"
(
    "ID" INT IDENTITY(1, 1) NOT NULL,
    "REGISTRY_GROUP" VARCHAR(50) NOT NULL,
    "REGISTRY_KEY" VARCHAR(255) NOT NULL,
    "REGISTRY_VALUE" VARCHAR(255) NOT NULL,
    "UPDATE_TIME" TIMESTAMP(0),
    NOT CLUSTER PRIMARY KEY("ID")) STORAGE(ON "MAIN", CLUSTERBTR) ;

CREATE  INDEX "I_G_K_V" ON "SYSDBA"."XXL_JOB_REGISTRY"("REGISTRY_GROUP" ASC,"REGISTRY_KEY" ASC,"REGISTRY_VALUE" ASC) STORAGE(ON "MAIN", CLUSTERBTR) ;
CREATE UNIQUE  INDEX "INDEX1270631893400000" ON "SYSDBA"."XXL_JOB_REGISTRY"("ID" ASC) STORAGE(ON "MAIN", CLUSTERBTR) ;


CREATE TABLE "SYSDBA"."XXL_JOB_USER"
(
    "ID" INT IDENTITY(1, 1) NOT NULL,
    "USERNAME" VARCHAR(50) NOT NULL,
    "PASSWORD" VARCHAR(50) NOT NULL,
    "ROLE" TINYINT NOT NULL,
    "PERMISSION" VARCHAR(255),
    NOT CLUSTER PRIMARY KEY("ID"),
    CONSTRAINT "I_USERNAME" UNIQUE("USERNAME")) STORAGE(ON "MAIN", CLUSTERBTR) ;

COMMENT ON COLUMN "SYSDBA"."XXL_JOB_USER"."PASSWORD" IS '密码';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_USER"."PERMISSION" IS '权限:执行器ID列表,多个逗号分割';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_USER"."ROLE" IS '角色:0-普通用户、1-管理员';
COMMENT ON COLUMN "SYSDBA"."XXL_JOB_USER"."USERNAME" IS '账号';
CREATE UNIQUE  INDEX "PRIMARY" ON "SYSDBA"."XXL_JOB_USER"("ID" ASC) STORAGE(ON "MAIN", CLUSTERBTR) ;

三、如果你的达梦数据库配置的是大小写敏感,可以通过mybatis的拦截器实现将达梦查询语句中的列转化为大写

package com.xxl.job.admin.core.interceptor;
import org.apache.ibatis.executor.CachingExecutor;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.plugin.*;

import java.util.Properties;

@Intercepts({
        //@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, org.apache.ibatis.session.RowBounds.class, org.apache.ibatis.session.ResultHandler.class}),
        @Signature(type = CachingExecutor.class, method = "update", args = {MappedStatement.class, Object.class})
})
public class UpperCase implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object[] args = invocation.getArgs();
        MappedStatement ms = (MappedStatement) args[0];
        String sql = ms.getBoundSql(args[1]).getSql();
        //将小写转化为大写
        String upperCaseSQL = sql.toUpperCase();

        BoundSql boundSql = ms.getBoundSql(args[1]);
        // 重新塞回去
        BoundSql newBoundSql = new BoundSql(ms.getConfiguration(), upperCaseSQL, boundSql.getParameterMappings(), boundSql.getParameterObject());
        MappedStatement newMs = newMappedStatement(ms, newBoundSql);
        for (ParameterMapping mapping : boundSql.getParameterMappings()) {
            String prop = mapping.getProperty();
            if (boundSql.hasAdditionalParameter(prop)) {
                newBoundSql.setAdditionalParameter(prop, boundSql.getAdditionalParameter(prop));
            }
        }
        args[0] = newMs;

        return invocation.proceed();
    }

    private MappedStatement newMappedStatement(MappedStatement ms, BoundSql newBoundSql) {
        MappedStatement.Builder builder = new
                MappedStatement.Builder(ms.getConfiguration(), ms.getId(), new BoundSqlSource(newBoundSql), ms.getSqlCommandType());
        builder.resource(ms.getResource());
        builder.fetchSize(ms.getFetchSize());
        builder.statementType(ms.getStatementType());
        builder.keyGenerator(ms.getKeyGenerator());
        if (ms.getKeyProperties() != null && ms.getKeyProperties().length > 0) {
            builder.keyProperty(ms.getKeyProperties()[0]);
        }
        builder.timeout(ms.getTimeout());
        builder.parameterMap(ms.getParameterMap());
        builder.resultMaps(ms.getResultMaps());
        builder.resultSetType(ms.getResultSetType());
        builder.cache(ms.getCache());
        builder.flushCacheRequired(ms.isFlushCacheRequired());
        builder.useCache(ms.isUseCache());

        return builder.build();
    }

    class BoundSqlSource implements SqlSource {
        private BoundSql boundSql;

        public BoundSqlSource(BoundSql boundSql) {
            this.boundSql = boundSql;
        }

        public BoundSql getBoundSql(Object parameterObject) {
            return boundSql;
        }
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
    }
}

注:

四、配置添加mybatis-config.xml配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
   <plugins>
        <plugin interceptor="com.xxl.job.admin.core.interceptor.UpperCase"/>
    </plugins>

</configuration>

五、在application.properties配置路径

mybatis.config-location= classpath:/mybatis-config.xml

六、修改相关的sql

详情可以查看码云完整代码「链接」

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表