java工程中如何正确使用kettle,XxlJob + kettle + redis实现增量更新

看了网上的一些关于kettle增量更新的文章,实在是没法拿来用啊,不是全量更新,就是要改数据库,一点都不清爽,只能自己整理一下了

kettle安装部署:你们随便找找吧,这里不负责

XxlJob安装部署,自己百度

redis安装部署,自己百度

我只讲kettle和java的整合,因为xxljob可以用定时器来实现,redis也不是必须,不是这次文章的核心,但是我觉得这样搭建的工程最爽

目录

1.进到kettle目录 data-integration,执行 ./spoon.sh 开始启动了

2.设置jndi

3.新建转换

4.在kettle里设置数据库连接

5.进入核心对象>>输入>>拖动表输入编辑

6.进入核心对象>>输出>>拖动插入/更新,并用连接线连接

7.启动试试,将之前设置的变量值设置一下看看

8.代码整合整合,中间排了一下包,特别是javax.servlet-api会有冲突

 9.配置JNDI和同步文件与代码结合

 10.XxlJob的配置,这里可以是定时任务


1.进到kettle目录 data-integration,执行 ./spoon.sh 开始启动了

2.设置jndi

        进入kettle 的根目录 data-integration/simple-jndi 修改 jdbc.properties 文件

        这个跟我们自己在应用中的配置是一样一样的,比如mysql:

jdbc:mysql://172.10.10.10:3306/test?characterEncoding=utf8&useSSL=true&serverTimezone=Asia/Shanghai&allowMultiQueries=true
live_logging_info/type=javax.sql.DataSource
live_logging_info/driver=org.postgresql.Driver
live_logging_info/url=jdbc:postgresql://localhost:5432/hibernate?searchpath=pentaho_dilogs
live_logging_info/user=hibuser
live_logging_info/password=password

        live_logging_info 就是JNDI的名字

3.新建转换

4.在kettle里设置数据库连接

选择数据库类型和连接方式,并设置JNDI 为之前配置好的JNDI,最后别忘记设置共享

5.进入核心对象>>输入>>拖动表输入编辑

此处第四步不确定可以先不加条件,然后点击预览,会不会出来数据,如果有数据再把4的条件加上去

点击预览的效果是这样的,如果没有数据的话,检查表里面是不是没有数据,或者库的名称不对

6.进入核心对象>>输出>>拖动插入/更新,并用连接线连接

        

7.启动试试,将之前设置的变量值设置一下看看

如果有错误的话看下日志,比如我这个就是表不存在,就要看下输入这里的表是不是能正常执行,修改相应的sql就好了

        

正确执行是这样的

保存好文件,恭喜,到这里,就完成了一半了,开始上代码

8.代码整合整合,中间排了一下包,特别是javax.servlet-api会有冲突
 <dependency>
            <groupId>pentaho-kettle</groupId>
            <artifactId>kettle-core</artifactId>
            <version>9.3.0.0-428</version>
            <exclusions>
                <exclusion>
                    <groupId>commons-collections</groupId>
                    <artifactId>commons-collections</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>commons-io</groupId>
                    <artifactId>commons-io</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>pentaho-kettle</groupId>
            <artifactId>kettle-dbdialog</artifactId>
            <version>9.3.0.0-428</version>
            <exclusions>
                <exclusion>
                    <artifactId>guava</artifactId>
                    <groupId>com.google.guava</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>pentaho-kettle</groupId>
            <artifactId>kettle-engine</artifactId>
            <version>9.3.0.0-428</version>
            <exclusions>
                <exclusion>
                    <artifactId>hibernate-commons-annotations</artifactId>
                    <groupId>org.hibernate</groupId>
                </exclusion>
                <exclusion>
                    <groupId>javax.servlet</groupId>
                    <artifactId>javax.servlet-api</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>pentaho</groupId>
                    <artifactId>mondrian</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>pentaho</groupId>
            <artifactId>metastore</artifactId>
            <version>9.3.0.0-428</version>
        </dependency>
kettle:
  log-file-path: ./logs/kettle-logs
  encoding: utf-8
  kettle-home: /Users/xu/resources/kettle/
  kettle-jndi-home: /Users/xu/resources/kettle/jndi/

 上面那步的home和jndi配合第9步


import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import java.nio.charset.Charset;

/**
 * 配置在yml文件中的常量数据
 *
 * @author lyf
 */
@Configuration
@Data
@ConfigurationProperties(prefix = "kettle")
public class KettleConfig {

    /**
     * 日志文件输出路径
     */
    public String logFilePath;

    /**
     * kettle编码设置
     */
    public Charset encoding;

//    /**
//     * ktr或kjb文件保存路径,单个文件执行的时候需要保存ktr、kjb文件
//     */
//    public String uploadPath;

    /**
     * kettle所在路径,初始化会自动生成.kettle文件在该目录,kettle.properties,repositories.xml,shared.xml都在里面
     */
    public String kettleHome;
    /**
     * kettle所在路径,初始化会自动生成.kettle文件在该目录,kettle.properties,repositories.xml,shared.xml都在里面
     */
    public String kettleJndiHome;

    /**
     * kettle插件包所在路径 eg: D:\Development\kettle\8.3\data-integration\plugins
     */
    public String kettlePluginPackages;

    public String kettlePluginBaseFolder;

//    public String kettleLogLevel;

}

@Service
@Slf4j
public class DateSyncJob {

    private final String DEFAULT_START_TIME = "2023-09-01 00:00:00";
    private final String DEFAULT_START_TIME_KEY = "#1LASTTIME";

    @Resource
    private RedissonClient redissonClient;

    @Autowired
    private KettleConfig kettleConfig;

    //同步任务
    public static final String SYNC_EQUIPMENT_ALARM_RECORD = "SYNC_EQUIPMENT_ALARM_RECORD";
 

    @PostConstruct
    public void init() {
        try {
            //初始化配置文件
            log.info("KETTLE HOME:"+kettleConfig.getKettleHome());
            Properties properties = System.getProperties();
            properties.put("KETTLE_HOME", kettleConfig.getKettleHome());
            Const.JNDI_DIRECTORY = kettleConfig.getKettleJndiHome() ;
            // 环境
            KettleEnvironment.init();
            EnvUtil.environmentInit();
            log.info("Kettle环境初始化成功");
        } catch (Exception e) {
            log.error("Kettle环境初始化失败", e);
        }
    }

    /**
     * 同步produce_risk_config
     */
    @XxlJob(SYNC_PRODUCE_RISK_CONFIG)
    public void produceRiskConfigJob() throws KettleException {
                sync(SYNC_PRODUCE_RISK_CONFIG,XxlJobHelper.getJobParam(),"produce_risk_config.ktr");
    }


    /**
     * 同步
     * @param jobName
     * @param jobParam
     * @param source
     */
    private void sync(String jobName,String jobParam,String source){
        String startTime = DEFAULT_START_TIME;
        //上次执行时间
        String lastTiem = DateUtils.getTime();

        String day = DateUtils.getDate();
        //如果最后一次执行时间为空,则全量执行一次,否则从上次执行时间开始同步数据,每天全量同步一次
        RBucket<String> accessTokenBucket = redissonClient.getBucket(jobName+ day + DEFAULT_START_TIME_KEY);
        if(accessTokenBucket.isExists()){
            startTime = accessTokenBucket.get();
        }

        //手动执行的时候
        if(StringUtils.isNotBlank(jobParam)){
            startTime = jobParam;
        }

        try {
//            ClassPathResource classPathResource = new ClassPathResource(source);
            handler(kettleConfig.getKettleHome() + source,startTime);
            //将上次执行时间放到缓存
            accessTokenBucket.set(lastTiem,2L*24L*60L, TimeUnit.MINUTES);
        }catch (Exception e){
            log.error("Kettle执行失败:{}", jobName);
            log.error(e.getMessage(),e);
        }
    }


    public void handler(String path, String startTime) throws KettleException {
        TransMeta tm = new TransMeta(path);
        Trans trans = new Trans(tm);
        LogChannel logChannel = new LogChannel(trans.getName() + "_" +System.currentTimeMillis());
        trans.setLog(logChannel);
        //设置参数
        trans.setParameterValue("start_time", "'"+startTime+"'");
        trans.setVariable("start_time", "'"+startTime+"'");

        trans.execute(null);
        // 线程等待,直到ktr执行完成
        trans.waitUntilFinished();
        // 执行完成后获取日志
        String logText = KettleLogUtil.getLogText(trans.getLogChannelId(), true, trans.getLogDate().getTime());
        log.info("=======>"+logText);

        // 判断执行过程中是否有错误, 有错误就抛出错误日志
        if (trans.getErrors() > 0) {
            throw new KettleException(logText);
        }
    }
}

这里是通过保存上次同步的时间来进行增量同步,数据库要能查询update_time,否则无法实现 

 9.配置JNDI和同步文件与代码结合

        将jndi和ktr文件放到文件夹里

 10.XxlJob的配置,这里可以是定时任务

        

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值