springboot整合定时任务

最近在做定时任务的时候,引发了许多思考。我们在springboot项目开发定时任务需求时,首先想到的是@Scheduled和启动类上的@EnableScheduling注解。无可厚非,这种注解方式的定时任务简单易操作。但我在想,如果有多个服务启动的话,会发生什么呐?我在idea中启动了两个端口不同的服务

 然后等定时任务的执行,在定时任务执行的时候,发现两个服务都执行了定时任务,这样就相当于跑了两次定时任务,这样肯定是万万不行的。比如我下面的测试栗子:我在用户表中查询年龄=18的用户,然后把查询到的结果插入到student表中

 本来我的表中符合条件就三条数据,插入到student表三条数据才合理,等执行完毕后,发现student表插入了六条数据,相当于定时任务重复执行了两遍,这样的执行结果肯定和本意是相悖的。那有什么办法在多个服务部署的情况下,可以避免不被同时执行呐,我首先想到了在开发中经常使用的redis分布式锁。

 执行完毕后,student表数据确实只有三条数据,达到了理想中的效果。可是用锁的话,肯定会影响性能,如果在开发中,需要用到的定时任务比较多,而且执行的时间比较长的话,这样肯定会有响应性能的。如果我建一张第三方的表,以用户表的id为主键,这样用主键唯一的特性,会不会避免重复执行的发生呐

 执行完毕后,student表数据确实只有三条数据,达到了理想中的效果。我个人觉得,如果在数据量比较小的情况下,用这样一种方式是没有问题的,但是如果数据量很大的话,那么建的第三方的表就会产生大量的数据。那在如今主流的开发中,有没有一种已经开发好的框架,可以避免重复执行并且又简单易操作的,我想到了现在比较主流的xxl-job。具体的xxl-job介绍大家可以查找资,我在这里只介绍如何在我们的项目中如何集成xxl-job。

1、安装调度中心:http://gitee.com/xuxueli0323/xxl-job(gitee地址)

下载之后,打开之后是这样的

找到 doc目录下的sql文件,在自己本地执行。然后修改xxl-job-admin下的配置文件

 

 修改后,直接启动admin项目即可,另外两个项目暂时不用管。

启动成功后,访问http://localhost:8081/xxl-job-admin/。我这里把端口改成了8081,默认8080

账号密码:admin/123456。登录成功后页面是这样的

 调度中心启动没问题后,就可以在我们的项目中整合调度中心配置,把我们的项目注册到调度中心中

2、引入xxl-job依赖

<dependency>
    <groupId>com.xuxueli</groupId>
    <artifactId>xxl-job-core</artifactId>
    <version>2.3.0</version>
</dependency>

3、在我们的项目配置文件yml中配置调度中心的信息

# Xxl-Job分布式定时任务调度中心
xxl:
    job:
        admin:
            # 调度中心部署跟地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。
            addresses: http://localhost:8081/xxl-job-admin
            # addresses: http://192.168.110.2:9090/xxl-job-admin
        # 执行器通讯TOKEN [选填]:非空时启用 系统默认 default_token
        accessToken: default_token
        executor:
            # 执行器的应用名称
            appname: mls-xxl-job
            # 执行器注册 [选填]:优先使用该配置作为注册地址
            address: ""
            # 执行器IP [选填]:默认为空表示自动获取IP
            ip: ""
            # 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999
            port: 9999
            # 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;
            logpath: D:\Work\xxlJob
            #logpath: /data/logs/mls/job
            # 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能;
            logretentiondays: 7

4、执行器配置文件

@Configuration
@Slf4j
public class XxlJobConfig {
    
    @Value("${xxl.job.admin.addresses}")
    private String adminAddresses;
    
    @Value("${xxl.job.accessToken}")
    private String accessToken;
    
    @Value("${xxl.job.executor.appname}")
    private String appname;
    
    @Value("${xxl.job.executor.address}")
    private String address;
    
    @Value("${xxl.job.executor.ip}")
    private String ip;
    
    @Value("${xxl.job.executor.port}")
    private int port;
    
    @Value("${xxl.job.executor.logpath}")
    private String logPath;
    
    @Value("${xxl.job.executor.logretentiondays}")
    private int logRetentionDays;
    
    @Bean
    public XxlJobSpringExecutor xxlJobExecutor() {
        
        log.info(">>>>>>>>>>> xxl-job config init.");
        XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
        xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
        xxlJobSpringExecutor.setAppname(appname);
        xxlJobSpringExecutor.setAddress(address);
        xxlJobSpringExecutor.setIp(ip);
        xxlJobSpringExecutor.setPort(port);
        xxlJobSpringExecutor.setAccessToken(accessToken);
        xxlJobSpringExecutor.setLogPath(logPath);
        xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
        
        return xxlJobSpringExecutor;
    }
}

以上配置结束后,在调度中心新增我们配置的执行器

 配置完毕后,启动项目,调度中心就可以查看注册成功的执行器了

 5、在项目中添加我们想要执行定时任务的方法

@XxlJob("xxlJobTest")
public void xxlJobTest() throws Exception {

    System.out.println("执行定时任务");
    QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
    wrapper.eq("age", 18);
    List<UserEntity> userEntityList = mqMapper.selectList(wrapper);
    Thread.sleep(5000);
    for (UserEntity entity : userEntityList) {
        StudentEntity studentEntity = new StudentEntity();
        studentEntity.setName(entity.getName() + entity.getAge());
        studentMapper.insert(studentEntity);
        entity.setAge(19);
        mqMapper.updateById(entity);
    }
}

 @XxlJob("xxlJobTest")中指定的名称为调度中心需要配置的名称

6、在调度中心配置我们上面添加的定时任务方法

 

保存后,我们的定时任务方法就添加成功了,下面只需要执行我们刚才添加的那个任务即可

 这样,我们的定时任务就执行成功了。

以上,就是关于定时任务我的一些思考。当然,还有一些别的问题,当有多个服务启动时,我们的定时任务会不会重复执行,还有当有多个服务时,如何让定时任务像多线程那样执行,比如第一个服务的定时任务只查询表中id为奇数的数据进行处理。比如第二个服务的定时任务只查询表中id为偶数的数据进行处理等等问题,这样xxl-job做完一个分布式的定时任务已经都处理好了,我也会在下篇文章中介绍。

如果写的有什么问题,可留言。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值