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

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

Go to download

uw-task包是一个分布式任务框架,通过uw-task可以快速构建基于docker的分布式任务体系,同时支持基于influx的任务运维监控。

The newest version!
package uw.task.util;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
import org.springframework.stereotype.Component;

/**
 * 基于redis实现的分布式序列。
 * 
 * @author axeon
 *
 */
@Component
public class GlobalSequenceManager {

	private static final Logger log = LoggerFactory.getLogger(GlobalSequenceManager.class);

	private static final String REDIS_TAG = "_SEQUENCE_";

	@Autowired
	private StringRedisTemplate template;

	private ConcurrentHashMap map = new ConcurrentHashMap<>();

	/**
	 * 获得序列值
	 * 
	 * @param name
	 * @return
	 */
	public long nextId(String name) {
		long seq = -1;
		try {
			RedisSequence limiter = map.get(name);
			if (limiter == null) {
				initLimiter(name, 100);
				limiter = map.get(name);
			}
			if (limiter != null) {
				seq = limiter.nextId();
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}

		return seq;
	}

	/**
	 * 初始化一个序列发生器
	 * 
	 * @param name
	 *            名称
	 * @param incrementNum
	 *            每次递增的数量
	 * @return
	 */
	public synchronized boolean initLimiter(String name, int incrementNum) {
		boolean flag = false;
		try {
			RedisSequence limiter = map.get(name);
			if (limiter == null) {
				limiter = new RedisSequence(name, incrementNum);
				map.put(name, limiter);
				flag = true;
			} else {
				if (limiter.getIncrementNum() != incrementNum) {
					limiter.setIncrementNum(incrementNum);
				}
				flag = false;
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}
		return flag;
	}

	/**
	 * redis序列发生器。
	 * 
	 * @author axeon
	 *
	 */
	class RedisSequence {

		/**
		 * 限速器名称
		 */
		String name;

		/**
		 * 当前数值
		 */
		AtomicLong currentId = new AtomicLong(0);

		/**
		 * 当前可以获取的最大id
		 */
		private long maxId;

		/**
		 * 增量数
		 */
		private int incrementNum;

		/**
		 * redis计数器
		 */
		private RedisAtomicLong counter;

		/**
		 * @return the name
		 */
		public String getName() {
			return name;
		}

		/**
		 * @param name
		 *            the name to set
		 */
		public void setName(String name) {
			this.name = name;
		}

		/**
		 * @return the incrementNum
		 */
		public int getIncrementNum() {
			return incrementNum;
		}

		/**
		 * @param incrementNum
		 *            the incrementNum to set
		 */
		public void setIncrementNum(int incrementNum) {
			this.incrementNum = incrementNum;
		}

		/**
		 * 初始化一个序列器
		 * 
		 * @param limitRate
		 *            限速速率
		 * @param limitTimeUnit
		 *            限速时间单位
		 * @param limitTimeValue
		 *            限速时间数值
		 */
		public RedisSequence(String name, int incrementNum) {
			super();
			this.name = name;
			this.incrementNum = incrementNum;
			counter = new RedisAtomicLong(REDIS_TAG + name, template.getConnectionFactory());
			currentId.set(counter.getAndAdd(incrementNum));
			maxId = currentId.get() + incrementNum;
		}

		/**
		 * 获得下一个ID
		 * 
		 * @param permits
		 * @return 如果为超限则返回0,否则返回需要等待的秒数
		 */
		synchronized long nextId() {
			long value = currentId.incrementAndGet();
			if (value >= maxId) {
				currentId.set(counter.getAndAdd(incrementNum));
				maxId = currentId.get() + incrementNum;
			}
			return value;
		}

	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy