记录工作问题 -- 解决多实例情况下:定时任务重复执行的问题

记录工作问题 -- 解决多实例情况下:定时任务重复执行的问题,第1张

记录工作问题 -- 解决多实例情况下:定时任务重复执行的问题

多实例情况下:定时任务重复执行的问题

前言一、不使用自动生效的定时任务二、使用redis 创建一个标识来判断(此处引用同事的想法)三、使用XXLJOB四、使用ShedLock + redis最后说明


前言

场景:现在集群越来越普及,一个服务拥有多个实例时,何如避免定时任务重复执行?


一、不使用自动生效的定时任务

详见:https://blog.csdn.net/qq_37700773/article/details/109385361?spm=1001.2014.3001.5501
但是不建议使用,原因是不方便。

二、使用redis 创建一个标识来判断(此处引用同事的想法)

定时任务启动的时候,先去redis查询是指定key是否存在值(这里使用reids 的AtomicLong)
这里使用的是redission,实质上执行的这句代码:

	// CacheUtil.incrAtomicLong(Key)这句代码的底层
    public long incrAtomicLong(String key) {
        return redissonClient.getAtomicLong(key).incrementAndGet();
    }

三、使用XXLJOB

xxljob是一个单独的服务,思路是:
1:业务系统内没有定时任务,而是将定时任务逻辑写成一个接口
2:在xxljob服务端管理台配置好参数,由xxljob服务定时调用业务系统
3:xxljob服务调用业务集群(xxljob请求网关/ng,最终请求哪个业务实例,由网关/ng规则决定)

xxljob这种模式,还是有点麻烦。而且我经常会忘记:还有xxljob?部署在哪?地址多少?


四、使用ShedLock + redis

推荐使用这个。对性能要求不是特别高的(性能要求在比肩某东、某宝的…这款肯定也不合适)
这个只是日常开发使用,董事任务的服务实例在十几个以内的,应该没啥问题。
推荐的主要原因是:很简单

spring项目中引入依赖:

        
        
        
            net.javacrumbs.shedlock
            shedlock-spring
            4.0.4
        
        
        
            net.javacrumbs.shedlock
            shedlock-provider-redis-spring
            2.5.0
        

增加shedLock的配置,使用的redis

package com.tao.scheduled.shedLock;

import net.javacrumbs.shedlock.core.LockProvider;
import net.javacrumbs.shedlock.provider.redis.spring.RedisLockProvider;
import net.javacrumbs.shedlock.spring.annotation.EnableSchedulerLock;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
 

@Configuration
@EnableSchedulerLock(defaultLockAtMostFor = "PT30M")
public class ShedLockConfig {
 
    @Bean
    public LockProvider lockProvider(RedisTemplate redisTemplate) {
        return new RedisLockProvider(redisTemplate.getConnectionFactory());
    }
 
}

最简单的定时任务代码

package com.tao.scheduled.shedLock;

import lombok.extern.slf4j.Slf4j;
import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;


@Slf4j
@Component
public class ShedLockDemo {

//    @Scheduled(cron = "0/2 * * * * ?")  每2秒执行一次
    @Scheduled(cron = "0/2 * * * * ?")
    @SchedulerLock(name = "scheduleDemo01")
    public void ScheduleDemo01() {
        log.info("开启定时任务......");

    }

}

启动类加上注:@EnableScheduling

//@EnableFeignClients//开启feign
@EnableSwagger2 //开启 Swagger
@SpringBootApplication
@EnableScheduling//开启定时任务
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class);
        System.out.println("======......项目启动成功......======"+ServerPortConfig.host+":"+ ServerPortConfig.serverPort);

    }
}

测试方法:
idea启动两个实例,直接观察日志…

最后说明

这篇文章,记录的是工作中遇到的问题,写的比较水。主要用于工作总结和记录

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5702133.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存