RedisUtil(哨兵模式)

/* 
 * Copyright (c) 2016, S.F. Express Inc. All rights reserved.
 */
package com.sf.novatar.tpl.redis.util;

import java.util.*;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import redis.clients.jedis.*;

/**
 * 描述:redis 工具类
 * 
 * <pre>
 * HISTORY
 * ****************************************************************************
 *  ID   DATE           PERSON          REASON
 *  1    2016年8月8日                   Create
 * ****************************************************************************
 * </pre>
 * 
 * @author 
 * @since 1.0
 */
@Component
public class RedisUtil {

	private final static Logger logger = LoggerFactory
			.getLogger(RedisUtil.class);

	@Value(value = "${REDIS_ADDR}")
	private String redis_addr;

	@Value(value = "${REDIS_SENTINEL}")
	private String redis_sentinel;

	@Value(value = "${REDIS_CLUSTERNAME}")
	private String redis_clustername;

	@Value(value = "${REDIS_AUTH}")
	private String redis_auth;

	@Value(value = "${REDIS_MAX_ACTIVE}")
	private String redis_max_active;

	@Value(value = "${REDIS_MAX_IDLE}")
	private String redis_max_idle;

	@Value(value = "${REDIS_MAX_WAIT}")
	private String redis_max_wait;

	@Value(value = "${REDIS_TIMEOUT}")
	private String redis_timeout;

	private static JedisPool jedisPool = null;
	private static JedisSentinelPool redisSentinelJedisPool = null;

	@PostConstruct
	private void initJedisPool() {
		try {
			JedisPoolConfig config = new JedisPoolConfig();
			config.setMaxTotal(Integer.parseInt(redis_max_active));
			config.setMaxIdle(Integer.parseInt(redis_max_idle));
			config.setMaxWaitMillis(Integer.parseInt(redis_max_wait));
			// 在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的
			config.setTestOnBorrow(true);
			// 哨兵模式
			if ("true".equalsIgnoreCase(redis_sentinel)) {
				Set<String> sentinels = getRedisSentinels(redis_addr);
				redisSentinelJedisPool = new JedisSentinelPool(
						redis_clustername, sentinels, config, redis_auth);
			} else {
				String address = redis_addr.split(":")[0];
				String port = redis_addr.split(":")[1];
				jedisPool = new JedisPool(config, address,
						Integer.parseInt(port),
						Integer.parseInt(redis_timeout), redis_auth);
			}
		} catch (Exception e) {
			if (logger.isInfoEnabled()) {
				logger.info(e.getMessage());
			}
			e.printStackTrace();
		}
	}

	private Set<String> getRedisSentinels(String redis_addr2) {
		Set<String> sentinelSet = new HashSet<String>();
		for (String sentinel : redis_addr2.split("\\|")) {
			sentinelSet.add(sentinel);
		}
		return sentinelSet;
	}

	@PreDestroy
	private void destroyJedisPool() {
		if ("true".equalsIgnoreCase(redis_sentinel)) {
			if (redisSentinelJedisPool != null) {
				redisSentinelJedisPool.destroy();
			}
		} else {
			if (jedisPool != null) {
				jedisPool.destroy();
			}
		}
	}

	/**
	 * 获取Jedis实例
	 * 
	 * @return
	 */
	public synchronized static Jedis getJedis() {
		Jedis resource = null;
		if (jedisPool != null) {
			try {
				resource = jedisPool.getResource();
			} catch (Throwable t) {
				if (resource != null) {
					resource.close();
					resource = null;
				}
			}
		} else if (redisSentinelJedisPool != null) {
			try {
				resource = redisSentinelJedisPool.getResource();
			} catch (Throwable t) {
				if (resource != null) {
					resource.close();
					resource = null;
				}
			}
		}
		return resource;
	}

	/**
	 * 释放jedis资源
	 * 
	 * @param jedis
	 */
	public static void returnResource(final Jedis jedis) {
		if (jedis != null) {
			jedis.close();
		}
	}

	public static void set(String key, String value) {
		Jedis jedis = null;
		try {
			jedis = getJedis();
			jedis.set(key, value);
		} catch (Exception e) {
			logger.info(e.getMessage());
		} finally {
			returnResource(jedis);
		}
	}

	public static void append(String key, String value) {
		Jedis jedis = null;
		try {
			jedis = getJedis();
			jedis.append(key, value);
		} catch (Exception e) {
			logger.info(e.getMessage());
		} finally {
			returnResource(jedis);
		}
	}

	public static Long del(String key) {
		Jedis jedis = null;
		try {
			jedis = getJedis();
			return jedis.del(key);
		} catch (Exception e) {
			logger.info(e.getMessage());
			return null;
		} finally {
			returnResource(jedis);
		}

	}

	public static String get(String key) {
		Jedis jedis = null;
		try {
			jedis = getJedis();
			return jedis.get(key);
		} catch (Exception e) {
			logger.info(e.getMessage());
			return "";
		} finally {
			returnResource(jedis);
		}
	}

	/**
	 * 设置值 并加上过期
	 * 
	 * @param key
	 * @param value
	 * @param seconds
	 */
	public static void setAndExpire(String key, String value, int seconds) {
		Jedis jedis = null;
		try {
			jedis = getJedis();
			jedis.set(key, value);
			jedis.expire(key, seconds);
		} catch (Exception e) {
			logger.info(e.getMessage());
		} finally {
			returnResource(jedis);
		}
	}

	/**
	 * 移除锁
	 * 
	 * @param jedis
	 *            Jedis 客户端
	 * @param lockName
	 *            锁名字,会加上前缀“lock:”
	 * @param identifier
	 *            锁的标识
	 * @return 是否移除成功
	 */
	public static boolean releaseLock(Jedis jedis, String lockName,
			String identifier) {
		lockName = String.format("lock:%s", lockName);
		while (true) {
			jedis.watch(lockName);
			if (identifier.equals(jedis.get(lockName))) {
				Transaction tx = jedis.multi();
				tx.del(lockName);
				List<Object> list = tx.exec();
				jedis.unwatch();
				if (list == null) {
					continue;
				}
				return true;
			} else {
				jedis.unwatch();
				break;
			}
		}
		return false;
	}

	/**
	 * 移除锁
	 * 
	 * @param lockName
	 *            锁名字,会加上前缀“lock:”
	 * @param identifier
	 *            锁的标识
	 * @return 是否移除成功
	 */
	public static boolean releaseLock(String lockName, String identifier) {
		Jedis jedis = RedisUtil.getJedis();
		boolean re;
		try {
			re = RedisUtil.releaseLock(jedis, lockName, identifier);
		} finally {
			RedisUtil.returnResource(jedis);
		}
		return re;
	}

	/**
	 * 获取锁
	 * 
	 * @param jedis
	 *            Jedis 客户端
	 * @param lockName
	 *            锁名字,会加上前缀“lock:”
	 * @param acquireTimeout
	 *            获取锁,重试时间(毫秒)
	 * @param lockTimeout
	 *            锁的自动过期时间(秒)
	 * @return 锁的标识
	 */
	public static String acquireLockWithTimeout(Jedis jedis, String lockName,
			int acquireTimeout, int lockTimeout) {
		String identifier = UUID.randomUUID().toString();
		lockName = String.format("lock:%s", lockName);
		long end = System.currentTimeMillis() + acquireTimeout;
		do {
			if (jedis.setnx(lockName, identifier) == 1) {
				jedis.expire(lockName, lockTimeout);
				return identifier;
			} else if (jedis.ttl(lockName) == -1) {
				jedis.expire(lockName, lockTimeout);
			}
			try {
				Thread.sleep(1);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		} while (System.currentTimeMillis() < end);
		return null;
	}

	/**
	 * 获取锁
	 * 
	 * @param lockName
	 *            锁名字,会加上前缀“lock:”
	 * @param acquireTimeout
	 *            获取锁,重试时间(毫秒)
	 * @param lockTimeout
	 *            锁的自动过期时间(秒)
	 * @return 锁的标识
	 */
	public static String acquireLockWithTimeout(String lockName,
			int acquireTimeout, int lockTimeout) {
		Jedis jedis = RedisUtil.getJedis();
		String identifier;
		try {
			identifier = RedisUtil.acquireLockWithTimeout(jedis, lockName,
					acquireTimeout, lockTimeout);
		} finally {
			RedisUtil.returnResource(jedis);
		}
		return identifier;
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值