利用Redis實現應用程式主備
阿新 • • 發佈:2018-12-12
需要實現主備的每個任務都先進行爭奪主機,通過爭奪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("RecodeScanServiceJob 未奪取主機執行權"); // 表示不是主機則睡眠兩倍時間再爭奪主機 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;
}
}