阅读量:1
1.pom中引入依赖,这里使用redis作为锁
<dependency> <groupId>net.javacrumbs.shedlock</groupId> <artifactId>shedlock-spring</artifactId> <version>4.12.0</version> </dependency> <dependency> <groupId>net.javacrumbs.shedlock</groupId> <artifactId>shedlock-provider-redis-spring</artifactId> <version>4.12.0</version> </dependency>
2.yml配置redis连接
spring: redis: host: localhost port: 6379 database: 0 taskrelease: taskrelease
3.配置redis序列化
@Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); // 使用Jackson2JsonRedisSerialize 替换默认序列化 Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); // 设置value的序列化规则和 key的序列化规则 redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.afterPropertiesSet(); return redisTemplate; } }
4.线程池和分布式锁配置
import lombok.extern.slf4j.Slf4j; 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.connection.RedisConnectionFactory; import org.springframework.scheduling.annotation.SchedulingConfigurer; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.scheduling.config.ScheduledTaskRegistrar; import javax.annotation.Resource; import java.util.concurrent.ExecutorService; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor; @EnableSchedulerLock(defaultLockAtMostFor = "PT30M") @Slf4j @Configuration public class ScheduleConfig implements SchedulingConfigurer { @Resource ExecutorService scheduledThreadPoolExecutor; /** * */ @Bean public ThreadPoolTaskExecutor threadPoolTaskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); //最大线程数 executor.setMaxPoolSize(8); //核心线程数 executor.setCorePoolSize(8); //任务队列的大小 executor.setQueueCapacity(100); //线程前缀名 executor.setThreadNamePrefix("common-"); //线程存活时间 executor.setKeepAliveSeconds(30); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy()); //线程初始化 executor.initialize(); return executor; } /** * 动态调度任务线程池 */ @Bean public ThreadPoolTaskScheduler threadPoolTaskScheduler() { ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); // 线程池大学 threadPoolTaskScheduler.setPoolSize(15); // 线程名称 threadPoolTaskScheduler.setThreadNamePrefix("taskScheduler-"); // 等待时长 threadPoolTaskScheduler.setAwaitTerminationSeconds(60); // 调度器shutdown被调用时等待当前被调度的任务完成 threadPoolTaskScheduler.setWaitForTasksToCompleteOnShutdown(true); return threadPoolTaskScheduler; } /** * Schedule定时任务指定线程池 * Spring注解 */ @Bean(name = "scheduledThreadPoolExecutor") public ScheduledThreadPoolExecutor scheduledThreadPoolExecutor() { return new ScheduledThreadPoolExecutor(15); } @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { //显式为Scheduler指定线程池 taskRegistrar.setScheduler(scheduledThreadPoolExecutor); } /** * 分布式锁 * Schedule定时任务, Spring注解 */ @Bean public LockProvider lockProvider(RedisConnectionFactory connectionFactory) { return new RedisLockProvider(connectionFactory, System.getProperty("spring.profiles.active")); } }
5.执行任务方法
@Scheduled(cron = "0 0 23 * * ?") @SchedulerLock(name = "synchronizeAddDept", lockAtLeastFor = "PT15S") public void synchronizeAddDept() { StopWatch watch = new StopWatch(); watch.start(); log.info("====================> 同步部门数据开始, {}", LocalDateTime.now()); watch.stop(); log.info("====================> 同步部门数据结束, {}, 用时 {}", LocalDateTime.now(), watch.getTotalTimeSeconds()); }