linux 定时任务pjp,spring boot 定时任务基于zookeeper的分布式锁实现

基于ZooKeeper分布式锁的流程

在zookeeper指定节点(locks)下创建临时顺序节点node_n

获取locks下所有子节点children

对子节点按节点自增序号从小到大排序

判断本节点是不是第一个子节点,若是,则获取锁;若不是,则监听比该节点小的那个节点的删除事件

若监听事件生效,则回到第二步重新进行判断,直到获取到锁

具体实现

添加Maven依赖:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

com.falsh

mytiming

1.0-SNAPSHOT

org.springframework.boot

spring-boot-starter-parent

2.0.4.RELEASE

UTF-8

UTF-8

1.8

org.springframework.boot

spring-boot-starter

org.springframework.boot

spring-boot-starter-quartz

org.springframework.boot

spring-boot-starter-aop

com.alibaba.spring.boot

dubbo-spring-boot-starter

2.0.0

spring-context

org.springframework

spring-core

org.springframework

org.apache.curator

curator-recipes

2.3.0

org.springframework.boot

spring-boot-maven-plugin

org.apache.maven.plugins

maven-source-plugin

attach-sources

jar

代码:

package com.falsh.tss.config;

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

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

import org.springframework.stereotype.Component;

@Component

public class CommonEnv {

public static String ZK_ADDRESS;

public static String ZK_LOCK_PATH;

@Autowired

public void setZkAddress(@Value("${zk.address}") String zkAddress) {

ZK_ADDRESS = zkAddress;

}

@Autowired

public void setZkLockPath(@Value("${zk.lock.path}") String zkLockPath) {

ZK_LOCK_PATH = zkLockPath;

}

}

package com.falsh.tss.global;

import org.aspectj.lang.ProceedingJoinPoint;

import org.aspectj.lang.annotation.Around;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Pointcut;

import org.aspectj.lang.reflect.MethodSignature;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.stereotype.Component;

import com.falsh.tss.mutex.MutexLock;

@Aspect

@Component

public class ControlExecJobAspect {

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

@Pointcut("execution(public * com.zhifu.tss.jobs..*(..))")

public void jobExec() {

}

@Around("jobExec()")

public void doAround(ProceedingJoinPoint pjp) throws Throwable{

String jobClass = pjp.getTarget().getClass().getSimpleName();

String methodName = ((MethodSignature) pjp.getSignature()).getMethod().getName();

if (!MutexLock.isInstantiated() || !MutexLock.getInstance().isAcquiredLock()) {

logger.info("-- None lock acquired ! {}.{} --", jobClass, methodName);

return;

}

logger.info("------- start {}.{} --------", jobClass, methodName);

long start = System.currentTimeMillis();

try {

pjp.proceed();

} catch (Exception e) {

logger.error("global erorr occured while {}.{}", jobClass, methodName, e);

}

long end = System.currentTimeMillis();

logger.info("------- end {}.{}({}ms) --------", jobClass, methodName, end - start);

}

}

package com.falsh.tss.jobs;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.scheduling.annotation.Scheduled;

import org.springframework.stereotype.Component;

@Component

public class MyJob1 {

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

@Scheduled(cron="${cron.job.myJob1}")

public void execute(){

logger.info("我在执行定时任务1.....");

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

package com.falsh.tss.mutex;

import static com.falsh.tss.config.CommonEnv.ZK_ADDRESS;

import static com.falsh.tss.config.CommonEnv.ZK_LOCK_PATH;

import org.apache.curator.framework.CuratorFramework;

import org.apache.curator.framework.CuratorFrameworkFactory;

import org.apache.curator.framework.recipes.locks.InterProcessLock;

import org.apache.curator.framework.recipes.locks.InterProcessMutex;

import org.apache.curator.retry.RetryNTimes;

import org.springframework.beans.factory.DisposableBean;

import org.springframework.beans.factory.InitializingBean;

public class MutexLock implements InitializingBean, DisposableBean {

private static CuratorFramework client;

private static InterProcessLock mutexLock;

private static volatile boolean acquiredLock;

private static volatile MutexLock instance;

public MutexLock() {

client = CuratorFrameworkFactory.newClient(ZK_ADDRESS, new RetryNTimes(10,5000));

client.start();

mutexLock = new InterProcessMutex(client, ZK_LOCK_PATH);

}

public static MutexLock getInstance(){

if (instance == null) {

synchronized (MutexLock.class) {

if (instance == null) {//二次检查

instance = new MutexLock();

}

}

}

return instance;

}

public static boolean isInstantiated() {

if (instance == null) {

return false;

}

return true;

}

//获取锁

public static void acquireMutexLock() throws Exception {

mutexLock.acquire();

acquiredLock = true;

}

//释放锁

public static void releaseMutexLock() throws Exception {

mutexLock.release();

}

public static boolean isAcquiredLock() {

return acquiredLock;

}

@Override

public void destroy() throws Exception {

}

@Override

public void afterPropertiesSet() throws Exception {

}

}

package com.falsh.tss;

import com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration;

import com.falsh.tss.mutex.MutexLock;

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.scheduling.annotation.EnableScheduling;

@EnableScheduling

@EnableDubboConfiguration

@EnableAutoConfiguration

@SpringBootApplication

@ComponentScan("com.zhifu")

public class Application {

private static final Log logger = LogFactory.getLog(Application.class);

public static void main(String[] args) {

SpringApplication.run(Application.class, args);

try {

MutexLock.getInstance().acquireMutexLock();

while (true) {

logger.warn("锁在我这");

Thread.sleep(60000);

}

} catch (Exception e) {

logger.info("获取锁失败", e);

} finally{

try {

MutexLock.getInstance().releaseMutexLock();

logger.warn("释放了锁");

} catch (Exception e) {

logger.error("释放锁异常", e);

}

}

}

}

配置:

application-dev.properties

spring.dubbo.application.name=myjobtss

spring.dubbo.registry.address=zookeeper://192.168.x.x:2181

spring.dubbo.protocol.name=dubbo

cron.job.myJob1=0 0/1 * * * ?

zk.address=192.168.x.x:2181

zk.lock.path=/myjob-quartz-locks

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值