zookeeper分布式锁解决集群定时任务重复执行问题

package cn.biz.impl;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;

/**
 * @Description 可动态更改时间的定时任务
 * @Author
 * @Date 2021/3/2
 * @Version 1.0.0
 */
@Component
public class SchedulingTask implements SchedulingConfigurer {

    private final Logger logger = LoggerFactory.getLogger(SchedulingTask .class);


    // cron表达式,我们动态更改此属性的值即可更改定时任务的执行时间
    private String expression = "0 0/2 * * * ?";

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {

        // 定时任务要执行的方法 
        Runnable task = () -> {
	       	//1、重试策略:初试时间为1s 重试3次
	        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
	        //2、通过工厂创建连接
	        CuratorFramework client = CuratorFrameworkFactory.newClient(zkAddress, retryPolicy);
	        //3、开启连接
	        client.start();
	        //4、获取zk分布式锁
	        InterProcessMutex mutex = new InterProcessMutex(client, "/curator/lock");
	 		boolean flag = false;
	        try {
	        	//尝试获取锁,最多等待0秒
	            flag = mutex.acquire(0, TimeUnit.SECONDS);
	            Thread currentThread = Thread.currentThread();
	            if(flag){//锁抢占成功 执行业务逻辑
	                logger.info(">>> configureTasks-----------【"+expression+"】");
	                 //开始业务逻辑
	            }
	            //
	            Thread.sleep(1000);
	        } catch (Exception e) {
	            e.printStackTrace();
	        } finally{
	            if(flag){
	                //1.先释放锁
                    if(flag){
                        try {
                            mutex.release();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    //2.后关闭zk客户端连接
                    if (client != null) {
                        client.close();
                    }
	            }
	        }
        };
        // 调度实现的时间控制
        Trigger trigger = triggerContext -> {
            CronTrigger cronTrigger = new CronTrigger(expression);
            return cronTrigger.nextExecutionTime(triggerContext);
        };
        taskRegistrar.addTriggerTask(task, trigger);
    }

    public String getExpression() {
        return expression;
    }

    public void setExpression(String expression) {
        this.expression = expression;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值