springboot实现多实例crontab抢占定时任务(实例代码)

网友投稿 274 2022-12-17


springboot实现多实例crontab抢占定时任务(实例代码)

github: https://github.com/jiasion/eslog

wechat:minghui-666

利用redisson实现多实例抢占定时任务

pom.xml

org.redisson

redisson

3.12.0

Kernel.java - 重写多线程调度

package com.brand.log.scheduler;

import org.springframework.context.annotation.Configuration;

import org.springframework.scheduling.annotation.SchedulingConfigurer;

import org.springframework.scheduling.config.ScheduledTaskRegistrar;

import java.util.concurrent.Executors;

@Configuration

public http://class Kernel implements SchedulingConfigurer {

@Override

public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {

//设定一个长度10的定时任务线程池

taskRegistrar.setScheduler(Executors.newScheduledThreadPool(4));

}

}

RedissonManager.java  -  分布式锁的实现

package com.brand.log.util;

import lombok.extern.slf4j.Slf4j;

import org.redisson.Redisson;

import org.redisson.config.Config;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

@Component

@Slf4j

public class RedissonManager {

@Value("${spring.redis.host}")

private String host;

@Value("${spring.redis.port}")

private int port;

private Redisson redisson = null;

private Config config = new Config();

@PostConstruct

private void init() {

try {

config.useSingleServer().setAddress("redis://" + host + ":" + port);

log.info("redisson address {} {}", host, port);

redisson = (Redisson) Redisson.create(config);

log.info("Redisson 初始化完成");

}

catch (Exception e) {

log.error("init Redisson error ", e);

}

}

public Redisson getRedisson() {

return redisson;

}

}

CronSynData.java

package com.brand.log.scheduler;

import com.brand.log.util.DateFormatV1;

import com.brand.log.util.RedisUtil;

import com.brand.log.util.RedissonManager;

import lombok.extern.slf4j.Slf4j;

import org.redisson.Redisson;

import org.redisson.api.RLock;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.scheduling.annotation.Scheduled;

import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component

@Slf4j

public class CronSynData {

@Autowired

RedissonManager redissonManager;

@Autowired

RedisUtil redisUtil;

@Autowired

DateFormatV1 dateFormatV1;

private String lokFlag PaLzCSOW= ".handleKernel";

private Redisson redisson = null;

/*

* java定时脚本挂靠实例

* 多实例会有重复调用问题 + 使用Redisson实现分布式锁

* 业务逻辑必须加锁 + 且需要保证 tryLock 等待时间小于cron的最小间隔执行时间

* */

@Scheduled(cron = "*/10 * * * * *")

public void handleKernel() {

redisson = redissonManager.getRedisson();

if (redisson != null) {

RLock lock = redisson.getLock(this.getClass().getName() + lokFlag);

Boolean stat = false;

try {

// 尝试加锁,立即返回,最多等待5s自动解锁

stat = lock.tryLock(0, 5, TimeUnit.SECONDS);

if (stat) {

log.info("{} 取锁成功!{}",this.getClass().getName(), Thread.currentThread().getName());

redisUtil.checkCount("log:limit_", dateFormatV1.getDate("HH", "GMT+8"), 60*10, 1000);

} else {

log.info("{}没有获取到锁:{}", this.getClass().getName(), Thread.currentThread().getName());

}

} catch (InterruptedException e) {

log.error("Redisson 获取分布式锁异常", e);

if (!stat){

return;

}

lock.unlock();

}

}

}

}

kibana - 6个实例

总结


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Spring Boot Debug调试过程图解
下一篇:spring AOP的After增强实现方法实例分析
相关文章

 发表评论

暂时没有评论,来抢沙发吧~