All Downloads are FREE. Search and download functionalities are using the official Maven repository.

uw.task.util.LeaderVote Maven / Gradle / Ivy

Go to download

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