uw.task.util.LeaderVote Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of uw-task Show documentation
Show all versions of uw-task Show documentation
uw-task包是一个分布式任务框架,通过uw-task可以快速构建基于docker的分布式任务体系,同时支持基于influx的任务运维监控。
The newest version!
package uw.task.util;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* 使用Reids的setnx+expire来选举Leader,来在多个运行实例中选举出一个运行全局任务的实例。
*
* @author axeon
*
*/
@Component
public class LeaderVote {
private static final Logger log = LoggerFactory.getLogger(LeaderVote.class);
private static final String REDIS_TAG = "_LEADER_VOTE_";
@Autowired
private StringRedisTemplate template;
/**
* 随机值。
*/
public static final String UUID = java.util.UUID.randomUUID().toString();
/**
* hashmap表。
*/
private ConcurrentHashMap map = new ConcurrentHashMap<>();
/**
* 全局唯一的UUID信息
*
* @return the uUID
*/
public String getUUID() {
return UUID;
}
/**
* 返回当前是否是Leader
*
* @return the isLeader
*/
public boolean isLeader(String name) {
VoteInfo vi = map.get(name);
if (vi == null) {
vi = initVoteInfo(name);
}
if (vi != null)
return vi.isLeader;
else
return false;
}
/**
* 初始化一个voteInfo信息。
*
* @param name
* @return
*/
private synchronized VoteInfo initVoteInfo(String name) {
VoteInfo vi = map.get(name);
if (vi == null) {
try {
vi = new VoteInfo();
vi.bvo = template.boundValueOps(REDIS_TAG + name);
map.put(name, vi);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
return vi;
}
/**
* 每20秒检查一次leader状态。
*
* @return true 为leaderStatus
*/
@Scheduled(fixedRate = 20000)
private void checkLeaderStatus() {
try {
for (Entry kv : map.entrySet()) {
if (kv.getValue().bvo == null)
continue;
// 使用setnx来抢leader身份
boolean flag = kv.getValue().bvo.setIfAbsent(UUID);
if (flag) {
// 再次确认身份,并更新expire。
if (UUID.equals(kv.getValue().bvo.get())) {
kv.getValue().bvo.expire(60, TimeUnit.SECONDS);
kv.getValue().isLeader = true;
} else {
kv.getValue().isLeader = false;
}
}
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
/**
* 投票信息
*
* @author axeon
*
*/
private static class VoteInfo {
BoundValueOperations bvo = null;
boolean isLeader = false;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy