利用Redis实现应用程序主备

<strong>需要实</strong>现主备的每个任务都先进行争夺主机,通过争夺redis中的key值。Rredis需要搭建主备高可用。

抢到key值的程序为主机,可以开始任务,备机线程开始等待,过段时间再进行争夺主机。一般情况下首先抢到key值的主机会一直执行任务直到主机异常,程序崩溃等错误发生时,备机才有可能抢到key值,变为主机。

Main:

import java.util.Date;
import java.util.UUID;

public class Test {

    private static final String CODE = UUID.randomUUID().toString();
    private static final Integer TIMEOUT = 10;

	public static void main(String[] args) throws InterruptedException {
		while (true) {
			execute();
		}
	}

	private static void execute() throws InterruptedException {
		String threadKey = "MainScanThread";
		String threadTimeKey = "MainScanTime";
		String oldUuid = RedisOpr.get(threadKey);
		String oldTime = RedisOpr.get(threadTimeKey);
		System.out.println("开始争夺主机。。。");
		// 如果有其他进程在进行
		if (oldUuid != null && !oldUuid.equals(CODE)) {
			// 如果进程刚进行结束,并且其他线程一直在持续执行,那么返回
			// 表示主机信息失效时长
			if (oldTime != null && (new Date().getTime() - Long.parseLong(oldTime)) < TIMEOUT*10) {
				System.out.println("main 未夺取主机执行权");
				// 表示不是主机则睡眠两倍时间再争夺主机
				Thread.sleep(TIMEOUT * 2);
				return;
			}
		}
		RedisOpr.set(threadKey, CODE);
		// 保存当前时间
		RedisOpr.set(threadTimeKey, String.valueOf(new Date().getTime()));
		System.out.println("夺取成功。。。");
		//开始执行任务

	}
}

 RedisOpr :Redis基本操作工具类

import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;

import redis.clients.jedis.Jedis;

/**
 * 
 * @ClassName: RedisOpr
 * @Description: TODO(redis基本操作类)
 * @author zoe 
 * @date 2018年3月12日 上午11:31:55
 *
 */
public class RedisOpr {

	private static Logger log = Logger.getLogger(RedisOpr.class);

	/**
	 * @Title: saveObject @Description: 保存对象 @param key @param object @return
	 *         void @throws
	 */
	public static void saveObject(String key, Object object) {
		Jedis jedis = RedisUtil.getJedis();
		try {
			jedis.set(key.getBytes(), SerializeUtil.serialize(object));
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			RedisUtil.returnResource(jedis);
		}
	}

	/**
	 * @Title: set @Description: 保存key值 @param key @param value @return void @throws
	 */
	public static void set(String key, String value) {
		Jedis jedis = RedisUtil.getJedis();
		try {
			jedis.set(key, value);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			RedisUtil.returnResource(jedis);
		}
	}

	/**
	 * @Title: @Description: 获取key值 @param key @return void @throws
	 */
	public static String get(String key) {
		Jedis jedis = RedisUtil.getJedis();
		try {
			return jedis.get(key);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			RedisUtil.returnResource(jedis);
		}
		return null;
	}

	/**
	 * @Title: getObject @Description: 获取对象 @param key @param object @return
	 *         void @throws
	 */
	public static Object getObject(String key) {
		Jedis jedis = RedisUtil.getJedis();
		try {
			byte[] object = jedis.get(key.getBytes());
			if (object == null) {
				return null;
			}
			return SerializeUtil.unserialize(object);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			RedisUtil.returnResource(jedis);
		}
		return null;
	}

	/**
	 * @Title: lpush @Description: 向链表末尾添加数据 @param key @param value @return
	 *         void @throws
	 */
	public static void lpush(String key, String value) {
		Jedis jedis = RedisUtil.getJedis();
		try {
			jedis.lpush(key, value);
		} catch (Exception e) {
			log.error(e.getMessage());
		} finally {
			RedisUtil.returnResource(jedis);
		}
	}

	/**
	 * @Title: rpush @Description: 向链表末位添加数据 @param key @param value @return
	 *         void @throws
	 */
	public static void rpushObject(String key, Object object) {
		Jedis jedis = RedisUtil.getJedis();
		try {
			jedis.rpush(key.getBytes(), SerializeUtil.serialize(object));
		} catch (Exception e) {
			log.error(e.getMessage());
		} finally {
			RedisUtil.returnResource(jedis);
		}
	}

	/**
	 * @Title: rpush @Description: 向链表末位添加数据 @param key @param value @return
	 *         void @throws
	 */
	public static void rpush(String key, String value) {
		Jedis jedis = RedisUtil.getJedis();
		try {
			jedis.rpush(key, value);
		} catch (Exception e) {
			log.error(e.getMessage());
		} finally {
			RedisUtil.returnResource(jedis);
		}
	}

	/**
	 * @Title: llen @Description: 获得链表长度 @param key @return long @throws
	 */
	public static long llen(String key) {
		Jedis jedis = RedisUtil.getJedis();
		try {
			return jedis.llen(key.getBytes());
		} catch (Exception e) {
			log.error(e.getMessage());
		} finally {
			RedisUtil.returnResource(jedis);
		}
		return 0;
	}

	/**
	 * @Title: removeObject @Description: 删除key @param key @return void @throws
	 */
	public static void removeObject(String key) {
		Jedis jedis = RedisUtil.getJedis();
		try {
			jedis.del(key.getBytes());
		} catch (Exception e) {
			log.error("error:" + e.getMessage());
		} finally {
			RedisUtil.returnResource(jedis);
		}
	}

	/**
	 * @Title: rPop @Description: 取出并删除List最后一个元素 @param key @return String @throws
	 */
	public static String rPop(String key) {
		Jedis jedis = RedisUtil.getJedis();
		try {
			String object = jedis.rpop(key);
			if (object == null) {
				return null;
			}
			return object;
		} catch (Exception e) {
			log.error("error:" + e.getMessage());
		} finally {
			RedisUtil.returnResource(jedis);
		}
		return null;
	}

	/**
	 * @Title: lPop @Description: 取出并删除List第一个元素 @param key @return String @throws
	 */
	public static String lPop(String key) {
		Jedis jedis = RedisUtil.getJedis();
		try {
			String object = jedis.lpop(key);
			if (object == null) {
				return null;
			}
			return object;
		} catch (Exception e) {
			log.error("error:" + e.getMessage());
		} finally {
			RedisUtil.returnResource(jedis);
		}
		return null;
	}

	/**
	 * @Title: isExistsKey @Description: 判断key是否存在 @param key @return
	 *         boolean @throws
	 */
	public static boolean isExistsKey(String key) {
		Jedis jedis = RedisUtil.getJedis();
		try {
			return jedis.exists(key);
		} catch (Exception e) {
			log.error("error:" + e.getMessage());
		} finally {
			RedisUtil.returnResource(jedis);
		}
		return false;
	}

	public static void hset(String key, String field, String value) {
		Jedis jedis = RedisUtil.getJedis();
		try {
			jedis.hset(key, field, value);
		} catch (Exception e) {
			log.error("error:" + e.getMessage());
		} finally {
			RedisUtil.returnResource(jedis);
		}
	}

	/**
	 * @Title: getRedisQueueObject @Description: 获得告警队列对象 @param key @return
	 *         List<Integer> @throws
	 */
	@SuppressWarnings("unchecked")
	public static List<Integer> getRedisQueueObject(String key) {
		Jedis jedis = RedisUtil.getJedis();
		try {
			byte[] object = jedis.get(key.getBytes());
			if (object == null) {
				return null;
			}
			return (List<Integer>) SerializeUtil.unserialize(object);
		} catch (Exception e) {
			log.error("error:" + e.getMessage());
		} finally {
			RedisUtil.returnResource(jedis);
		}
		return null;
	}

	/**
	 * @Title: getRedisWarnState @Description: TODO(这里用一句话描述这个方法的作用) @param
	 *         key @param 获得告警队列状态 @return Integer @throws
	 */
	public static Integer getRedisWarnState(String key) {
		Jedis jedis = RedisUtil.getJedis();
		try {
			byte[] object = jedis.get(key.getBytes());
			if (object == null) {
				return null;
			}
			return (Integer) SerializeUtil.unserialize(object);
		} catch (Exception e) {
			log.error("error:" + e.getMessage());
		} finally {
			RedisUtil.returnResource(jedis);
		}
		return null;
	}

	/**
	 * @Title: getAllKeyByPattern @Description: 通过正则表达式获得key @param pattern @return
	 *         List<String> @throws
	 */
	public static Set<String> getAllKeyByPattern(String pattern) {
		Jedis jedis = RedisUtil.getJedis();
		try {
			return jedis.keys(pattern);
		} catch (Exception e) {
			log.error("error:" + e.getMessage());
		} finally {
			RedisUtil.returnResource(jedis);
		}
		return null;
	}

	/**
	 * @Title: getString @Description: redis获得string @param key @return
	 *         String @throws
	 */
	public static String getString(String key) {
		Jedis jedis = RedisUtil.getJedis();
		try {
			byte[] object = jedis.get(key.getBytes());
			if (object == null) {
				return null;
			}
			return (String) SerializeUtil.unserialize(object);
		} catch (Exception e) {
			log.error("error:" + e.getMessage());
		} finally {
			RedisUtil.returnResource(jedis);
		}
		return null;
	}

	/**
	 * @Title: lrange @Description: 获得链表指定范围内的数据 @param key @param start @param
	 *         end @return List<byte[]> @throws
	 */
	public static List<byte[]> lrange(String key, long start, long end) {
		Jedis jedis = RedisUtil.getJedis();
		try {
			return jedis.lrange(key.getBytes(), start, end);
		} catch (Exception e) {
			log.error("error:" + e.getMessage());
		} finally {
			RedisUtil.returnResource(jedis);
		}
		return null;
	}

	/**
	 * @Title: lindex @Description: 根据索引获得list数据 @param @param key @param @param
	 *         index @return byte[] @throws
	 */
	public static byte[] lindex(String key, long index) {
		Jedis jedis = RedisUtil.getJedis();
		try {
			return jedis.lindex(key.getBytes(), index);
		} catch (Exception e) {
			log.error("error:" + e.getMessage());
		} finally {
			RedisUtil.returnResource(jedis);
		}
		return null;
	}

}

RedisUtil:Redis初始化工具类

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * 
 * @ClassName: RedisUtil
 * @Description: TODO(redis初始化类)
 * @author zoe 
 * @date 2018年3月12日 上午11:32:17
 *
 */
public class RedisUtil {
	private static String ADDR = SystemProperties.getString("redis-ip");
	private static int PORT = SystemProperties.getInteger("redis-port");
	private static String PASSWORD = SystemProperties.getString("redis-pwd");
	private static String REDISPASSWORD = PASSWORD;
	private static int MAX_ACTIVE = 50;
	private static int MAX_IDLE = 10;
	private static int MAX_WAIT = 10000;
	private static int TIMEOUT = 10000;
	private static boolean TEST_ON_BORROW = true;
	private static JedisPool jedisPool = null;
	static {
		try {
			JedisPoolConfig config = new JedisPoolConfig();
			config.setMaxTotal(MAX_ACTIVE);
			config.setMaxIdle(MAX_IDLE);
			config.setMaxWaitMillis(MAX_WAIT);
			config.setTestOnBorrow(TEST_ON_BORROW);
			if (REDISPASSWORD == null || "".equals(REDISPASSWORD)) {
				jedisPool = new JedisPool(config, ADDR, PORT, TIMEOUT);
			} else {
				jedisPool = new JedisPool(config, ADDR, PORT, TIMEOUT, REDISPASSWORD);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public synchronized static Jedis getJedis() {
		try {
			if (jedisPool != null) {
				Jedis resource = jedisPool.getResource();
				return resource;
			} else {
				return null;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 释放jedis资源
	 * 
	 * @param jedis
	 */
	public static void returnResource(final Jedis jedis) {
		if (jedis != null) {
			jedisPool.returnResource(jedis);
		}
	}
}

SerializeUtil :序列化工具类

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 * 
 * @ClassName: SerializeUtil
 * @Description: TODO(序列化和反序列化)
 * @author zoe 
 * @date 2018年3月12日 上午11:35:26
 *
 */
public class SerializeUtil {
	public static byte[] serialize(Object object) {
		ObjectOutputStream oos = null;
		ByteArrayOutputStream baos = null;
		try {
			// 序列化
			baos = new ByteArrayOutputStream();
			oos = new ObjectOutputStream(baos);
			oos.writeObject(object);
			byte[] bytes = baos.toByteArray();
			return bytes;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static Object unserialize(byte[] bytes) {
		ByteArrayInputStream bais = null;
		try {
			// 反序列化
			bais = new ByteArrayInputStream(bytes);
			ObjectInputStream ois = new ObjectInputStream(bais);
			return ois.readObject();
		} catch (Exception e) {

		}
		return null;
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值