クラスタの下でredisを使用して分散ロックを実現し、1つのサーバだけがタイミングタスクを実行することを保証します.
21453 ワード
redisのsetnxタイミング分散ロックを利用して、コアコードは以下の通りです.
次は分散ロックツールクラスです
全体的に、エラーが発生するようです.私は方法を別々に書きます.以下のコードをツールクラスにコピーすればいいです.
錠をかける
リロードロック
ロック解除
タイミング補充キー時間
使用法mainメソッドを使用して以下のテストを行います.
以上のツールクラスは、プロジェクトクラスタのタイミングタスクの実行に適しています.具体的に何か分からないことがあったら、私を信用してください.
/**
* key , seconds
*
* @param key
* @param seconds
* @return
*/
public static boolean setLock(String key, int seconds) {
Jedis client = getJedis();
if (client == null) {
return false;
}
try {
Long lock = client.setnx(key, "1");
if (lock > 0) {
client.expire(key, seconds);
return true;
}
} catch (Exception e) {
return false;
} finally {
if (null != client) {
client.close();
}
}
return false;
}
次は分散ロックツールクラスです
/**
* @author hyd
*
*/
public class RedisDistributedLock {
// redisKey 。 key , 。
public static final Map<String, Timer> timerMap = new Hashtable<>();
//
private static final String REDIS_LOCK = "project:distribued:lock:";
// key ,
private static final int lockTime = 3 * 60;
}
全体的に、エラーが発生するようです.私は方法を別々に書きます.以下のコードをツールクラスにコピーすればいいです.
錠をかける
public static boolean lock(String key, int lockTime) {
String lockKey = REDIS_LOCK + key;
// redisCache redispool
boolean lock = setLock(lockKey, lockTime);
if (lock) {
redisLock(key, lockTime);
return lock;
}
return lock;
}
リロードロック
public static boolean lock(String key){
return lock(key, lockTime);
}
ロック解除
public static void releaseLock(String key) {
String lockKey = REDIS_LOCK + key;
RedisCache.getInstance().del(lockKey);
Timer timer = timerMap.get(key);
if (timer != null) {
timer.cancel();
}
}
タイミング補充キー時間
public static void redisLock(String key, int lockTime){
String lockKey = REDIS_LOCK + key;
//
ThreadPoolUtil.execute(new Runnable() {
@Override
public void run() {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
if (timerMap.get(key) != null) {
RedisCache.getInstance().expireLock(lockKey, lockTime);
}
}
}, 10, lockTime * 1000 / 3);
timerMap.put(key, timer);
});
}
}
使用法mainメソッドを使用して以下のテストを行います.
public static void main(String[] args) {
// , 3 。 , 。
String key = "reportTimer";
boolean lock = RedisDistributedLock.lock(key);
try {
if (lock) {
timerTask();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
RedisDistributedLock.releaseLock(key);
}
// , 3 。 , 。
String key1 = "reportTimer1";
boolean lock1 = RedisDistributedLock.lock(key1);
try {
if (lock1) {
timerTask();
}
} catch (Exception e) {
e.printStackTrace();
}
// , 5 。 , 。
String key2 = "reportTimer2";
boolean lock2 = RedisDistributedLock.lock(key2, 5 * 60);
try {
if (lock2) {
timerTask();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
RedisDistributedLock.releaseLock(key2);
}
// , 5 。 , 。
String key3 = "reportTimer3";
boolean lock3 = RedisDistributedLock.lock(key3, 5 * 60);
try {
if (lock3) {
timerTask();
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static void timerTask() {
System.out.println(" ! , ");
}
以上のツールクラスは、プロジェクトクラスタのタイミングタスクの実行に適しています.具体的に何か分からないことがあったら、私を信用してください.