2台服务器只执行一台的定时任务(redisson)

springboot2
下面的pom.xml


org.redisson
redisson
3.11.0


另外添加aop,为后面添加注释做准备

org.springframework.boot
spring-boot-starter-aop

创建2个类,用于管理redis


/**
 * 创建redis锁的类
 * @author wangmin33
 *
 */
public class DistributedRedisLock {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(DistributedRedisLock.class);
	// 从配置类中获取redisson对象
	private static Redisson redisson = RedissonManager.getRedisson();
	private static final String LOCK_TITLE = "redisLock_";
	private static String ip;//计划使用ip区分,后来没用
	
	 static {
		 InetAddress localHost = null;
	     try {
	       localHost = Inet4Address.getLocalHost();
	     } catch (UnknownHostException e) {
	    	 LOGGER.error(e.getMessage(),e);
	     }
	     ip = localHost.getHostAddress();  // 返回格式为:xxx.xxx.xxx
	 }
	
	// 加锁,一直等待获得锁
	public static boolean acquire(String lockName) {
		// 声明key对象
		String key = LOCK_TITLE + lockName;
		// 获取锁对象
		RLock mylock = redisson.getLock(key);
		// 加锁,并且设置锁过期时间,防止死锁的产生
		//加锁 锁的有效期默认30秒
		mylock.lock(2, TimeUnit.MINUTES);
		LOGGER.info(key+"======lock======" + Thread.currentThread().getName());
		// 加锁成功
		return true;
	}
	

	// 锁的释放
	public static void release(String lockName) {
		// 必须是和加锁时的同一个key
		String key = LOCK_TITLE + lockName;
		// 获取所对象
		RLock mylock = redisson.getLock(key);
		// 释放锁(解锁)
		mylock.unlock();
		LOGGER.info(key+"======unlock======" + Thread.currentThread().getName());
	}
	
	//尝试获取锁,如果获取不到就放弃
	public static boolean tryLock(String lockKey){
		// 声明key对象
		String key = LOCK_TITLE + lockKey;
        RLock lock = redisson.getLock(key);
        	/**
        	 * tryLock()方法是有返回值的,它表示用来尝试获取锁,如果获取成功,则返回true,如果获取失败(即锁已被其他线程获取),则返回false .
        	 */
    	// 加锁,并且设置锁过期时间,防止死锁的产生
        	LOGGER.info(key+"======trylock======" + Thread.currentThread().getName());
        	boolean islock=false;
        	try {
        		islock=lock.tryLock(1,120,TimeUnit.SECONDS);
			} catch (InterruptedException e) {
				LOGGER.info("error" + e.getMessage());
			}
        	return islock;
    }
	/**
	 * 尝试获取锁,
	 * @param lockKey 
	 * @param unit  等待时间的单位
	 * @param waitTime 等待获取锁的时间
	 * @param leaseTime 释放的时间
	 * @return
	 */
		public static boolean tryLock(String lockKey,TimeUnit unit,long waitTime,long leaseTime){
			// 声明key对象
			String key = LOCK_TITLE + lockKey;
			RLock lock = redisson.getLock(key);
	        try{
	            lock.tryLock(waitTime,leaseTime,unit);
	            return true;
	        }catch (InterruptedException e){
	        	LOGGER.info("error" + e.getMessage());
	            return false;
	        }
	    }
	
}
/**
 * 连接redis
 * @author wangmin33
 *
 */
public class RedissonManager {
	
	private static Config config = new Config();
	// 声明redisso对象
	private static Redisson redisson = null;
	// 实例化redisson
	static {
		config.useSingleServer().setAddress("redis://10.10.1.96:1111");
		config.useSingleServer().setPassword("33333");
		// 得到redisson对象
		redisson = (Redisson) Redisson.create(config);
	}
	
	private RedissonManager() {};

	// 获取redisson对象的方法
	public static Redisson getRedisson() {
		return redisson;
	}
}

创建controller类进行测试

package com.wang.redis.controller;

import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.wang.redis.service.RedisService;
import com.wang.redis.util.DistributedRedisLock;

@Controller
@RequestMapping("keepup")
public class KeepupController {
	private static final Logger LOGGER = LoggerFactory.getLogger(KeepupController.class);

	@Autowired
	private RedisService redisService;
	@Value("${redis.key}")
	private String redis_key;

	@RequestMapping("/redder")
	@ResponseBody
	public String redder() throws IOException {
		// 加锁
		boolean lock = DistributedRedisLock.tryLock(redis_key);
		if (lock) {
			// 执行具体业务逻辑
			LOGGER.info("aaaa222222");
			try {
				Thread.sleep(20000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
			}
			// 释放锁
			DistributedRedisLock.release(redis_key);
		} else {
			LOGGER.info("aaaa22222222放弃执行");
		}
		// 返回结果
		return "end";
	}

	@RequestMapping("/redder2")
	@ResponseBody
	public String redder2() throws IOException {
		// 加锁
		boolean lock = DistributedRedisLock.tryLock(redis_key);
		if (lock) {
			// 执行具体业务逻辑
			LOGGER.info("aaaa33333");
			// 释放锁
			DistributedRedisLock.release(redis_key);
		} else {
			LOGGER.info("aaaa33333放弃执行");
		}
		// 返回结果
		return "end";
	}

	@RequestMapping("/redder3")
	@ResponseBody
	public String redder3() throws IOException {
		redisService.run("3333333333");
		// 返回结果
		return "end";
	}

	@RequestMapping("/redder4")
	@ResponseBody
	public String redder4() throws IOException {
		redisService.run("44444444444");
		// 返回结果
		return "end";
	}

}

service

@RedisAnnotation
	public void run(String name) {
		// 执行具体业务逻辑
		LOGGER.info(name);
		try {
			Thread.sleep(20000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

添加自定义注解

package com.wang.redis.aop;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Target;
/**
 * @Target(ElementType.TYPE)   //接口、类、枚举、注解
@Target(ElementType.FIELD) //字段、枚举的常量
@Target(ElementType.METHOD) //方法
@Target(ElementType.PARAMETER) //方法参数
@Target(ElementType.CONSTRUCTOR)  //构造函数
@Target(ElementType.LOCAL_VARIABLE)//局部变量
@Target(ElementType.ANNOTATION_TYPE)//注解
@Target(ElementType.PACKAGE) ///包   
 * @author wangmin33
 *
 */
@Documented//说明该注解将被包含在javadoc中
//@Target:定义注解的作用目标
@Target({ElementType.METHOD,ElementType.PARAMETER})// 方法和方法参数
@Inherited//说明子类可以继承父类中的该注解
public @interface RedisAnnotation {
    /**
    * 如果注解只有一个属性,那么肯定是赋值给该属性。
     * 如果注解有多个属性,而且前提是这多个属性都有默认值,那么你不写注解名赋值,会赋值给名字为“value”这属性。
     * 如果注解有多个属性,其中有没有设置默认值的属性,那么当你不写属性名进行赋值的时候,是会报错的。
     */
     //@AliasFor("")起别名
    int value() default 000;

}

添加aop

package com.cloud.keepup.aop;

import java.util.HashMap;
import java.util.Map;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.cloud.keepup.controller.KeepupController;
import com.util.DistributedRedisLock;

/**
 * 自定义切面类:@Component必须要添加,否则无效
 *
 * <!-- 开启AspectJ自动代理--> <aop:aspectj-autoproxy />
 */
@Component
@Aspect
public class RedisAspect {

	private static final Logger LOGGER = LoggerFactory.getLogger(RedisAspect.class);
	@Value("${redis.key}")
	private String redis_key;

	@Pointcut("@annotation(com.cloud.keepup.aop.RedisAnnotation)")
	public void cut() {
	}

	@Around(value = "cut()")
	public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
		System.out.println("环绕前通知==========");
		// 加锁
		Object obj = null;
		boolean lock = DistributedRedisLock.tryLock(redis_key);
		if (lock) {
			obj = joinPoint.proceed();
			// 释放锁
			DistributedRedisLock.release(redis_key);
		} else {
			LOGGER.info("aaaa22222222放弃执行");
		}
		System.out.println("环绕后通知==========");
		return obj;
	}

}

在application里面添加
redis.key=test123

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值