package com.xiaomi.weather.vote.webservices.util.redisCache;

import com.google.common.base.Strings;
import org.apache.log4j.Logger;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig; import java.io.InputStream;
import java.util.*; /**
* Created by mi on 16-12-22.
*/
public class RedisClusterClient {
private static final Logger logger = Logger.getLogger(RedisClusterClient.class);
private static String isOn = "true"; // 是否启用缓存
private static JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); // 配置信息
public JedisCluster jedisCluster = null;
Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>(); public static RedisClusterClient redisClusterClient = new RedisClusterClient(); public RedisClusterClient() {
init();
} public static RedisClusterClient getInsance() {
if (redisClusterClient != null) {
return redisClusterClient;
} else {
redisClusterClient = new RedisClusterClient();
return redisClusterClient;
}
} public boolean init() {
try {
// 读取配置文件
InputStream path = RedisClusterClient.class.getClassLoader().getResourceAsStream("cache.properties");
Properties pros = new Properties();
pros.load(path);
this.isOn = pros.getProperty("redis.onoff", "true");// 默认开启缓存
if (this.isOn.equals("false")) {// 未开启缓存
return false;
} //
String servers = pros.getProperty("redisMultiCluster.clusters", null);
if (Strings.isNullOrEmpty(servers)) {
logger.error("RedisJavaClient.servers 配置错误; in file:cache.properties");
this.isOn = "false";
return false;
}
String[] hostAndPorts = servers.split("\\|");
for (int i = 0; i < hostAndPorts.length; i++) {
String hostAndPort = hostAndPorts[i];
if (!hostAndPort.contains(":")) {
return false;
}
jedisClusterNodes.add(new HostAndPort(hostAndPort.split(":")[0], Integer.parseInt(hostAndPort.split(":")[1])));
}
try {
jedisPoolConfig.setMaxTotal(Integer.parseInt(pros.getProperty("redisMultiCluster.maxTotal", "8")));
jedisPoolConfig.setMaxIdle(Integer.parseInt(pros.getProperty("redisMultiCluster.maxIdle", "8")));
jedisPoolConfig.setMinIdle(Integer.parseInt(pros.getProperty("redisMultiCluster.minIdle", "0")));
jedisPoolConfig
.setBlockWhenExhausted(Boolean.parseBoolean(pros.getProperty("redisMultiCluster.blockWhenExhausted", "true")));
jedisPoolConfig.setMaxWaitMillis(Integer.parseInt(pros.getProperty("redisMultiCluster.maxWaitMillis", "true")));
jedisPoolConfig.setTestOnBorrow(Boolean.parseBoolean(pros.getProperty("redisMultiCluster.testOnBorrow", "true")));
jedisPoolConfig.setTestOnCreate(Boolean.parseBoolean(pros.getProperty("redisMultiCluster.testOnCreate", "true")));
jedisPoolConfig.setTestOnReturn(Boolean.parseBoolean(pros.getProperty("redisMultiCluster.testOnReturn", "true")));
jedisPoolConfig.setTestWhileIdle(Boolean.parseBoolean(pros.getProperty("redisMultiCluster.testWhileIdle", "false"))); } catch (Exception e) {
logger.error("{未知异常}", e);
}
jedisCluster = new JedisCluster(jedisClusterNodes, jedisPoolConfig);
logger.info("缓存初始化成功");
path.close();
return true;
} catch (Exception e) {
logger.error("{缓存初始化错误}", e);
this.isOn = "false";
}
return false;
} public boolean setnx(String key, String value, int expireTime) {
if (!isOn.equals("true")) {
logger.info("缓存未开启");
return false;
}
try {
Long setSuccess = jedisCluster.setnx(key, value);
if (setSuccess == 1) {
if (1 == jedisCluster.expire(key, expireTime)) {
return true;
} else {
this.deleteKey(key);
return false;
}
} else {
return false;
}
} catch (Exception e) {
logger.error("{}", e);
}
return false;
} public boolean set(String key, String value, int expireTime) {
if (!isOn.equals("true")) {
logger.info("缓存未开启");
return false;
}
try {
jedisCluster.setex(key, expireTime, value);
return true;
} catch (Exception e) {
logger.error("{}", e);
}
return false;
} public String get(String key) {
if (!isOn.equals("true")) {
logger.info("缓存未开启");
return "";
}
try {
return jedisCluster.get(key);
} catch (Exception e) {
logger.error("{}", e);
}
return null;
} public <T> boolean setList(String key, List<T> list, Class<T> tClass, int expireTime) {
if (!isOn.equals("true")) {
logger.info("缓存未开启");
return false;
}
try {
if (this.setnx(key + "Lock", "true", expireTime)) {
this.deleteKey(key);
for (T t : list) {
jedisCluster.rpush(key, SerializationDefine.Object2String(t));
}
if (1 == jedisCluster.expire(key, expireTime)) {
return true;
} else {
this.deleteKey(key);
return false;
}
}
return true;
} catch (Exception e) {
logger.error("{}", e);
}
return false;
} public <T> List<T> getList(String key, Class<T> tClass) {
if (!isOn.equals("true")) {
logger.info("缓存未开启");
return null;
}
try {
List<T> tList = new ArrayList<T>();
List<String> strList = jedisCluster.lrange(key, 0L, -1L);
for (String str : strList) {
tList.add(SerializationDefine.String2Object(str, tClass));
} return tList.size() == 0 ? null : tList;
} catch (Exception e) {
logger.error("{}", e);
return null;
}
} public <T> boolean setMap(String key, Map<String, T> map, Class<T> tClass, int expireTime) {
if (!isOn.equals("true")) {
logger.info("缓存未开启");
return false;
}
Map<String, String> catchMap = new HashMap<String, String>();
if (this.setnx(key + "Lock", "true", expireTime)) {
this.deleteKey(key);
for (Map.Entry<String, T> entry : map.entrySet()) {
catchMap.put(entry.getKey(), SerializationDefine.Object2String(entry.getValue()));
}
jedisCluster.hmset(key, catchMap);
if (1 == jedisCluster.expire(key, expireTime)) {
return true;
} else {
this.deleteKey(key);
return false;
} }
return true;
} public <T> Map<String, T> getMap(String key, Class<T> tClass) {
if (!isOn.equals("true")) {
logger.info("缓存未开启");
return null;
}
try {
Map<String, String> catchMap = jedisCluster.hgetAll(key);
Map<String, T> retMap = new HashMap<String, T>();
for (Map.Entry<String, String> entry : catchMap.entrySet()) {
retMap.put(entry.getKey(), SerializationDefine.String2Object(entry.getValue(), tClass));
}
return retMap;
} catch (Exception e) {
logger.error("{}", e);
return null;
} } public boolean deleteKey(String key) {
if (!isOn.equals("true")) {
logger.info("缓存未开启");
return false;
}
try {
if (1 == jedisCluster.del(key)) {
return true;
} else {
throw new Exception("redis异常,删除key失败:method = deleteKey; key = " + key);
}
} catch (Exception e) {
logger.error("{严重异常}", e);
} return false;
} /**
* 加1操作
*
* @param key
* @return
*/
public boolean incr(String key) {
if (!isOn.equals("true")) {
logger.info("缓存未开启");
return false;
}
try {
jedisCluster.incr(key);
return true;
} catch (Exception e) {
logger.error("{}", e);
return false;
}
} /**
* 减1操作
*
* @param key
* @return
*/
public boolean decr(String key) {
if (!isOn.equals("true")) {
logger.info("缓存未开启");
return false;
}
try {
jedisCluster.decr(key);
return true;
} catch (Exception e) {
logger.error("{}", e);
return false;
}
} /**
* 判断是否已缓存
*
* @param key
* @return
*/
public boolean isExist(String key) {
if (!isOn.equals("true")) {
logger.info("缓存未开启");
return false;
}
try {
return jedisCluster.exists(key);
} catch (Exception e) {
return false;
}
}
}

RedisClusterClient

说明,当redis连接不够用时,此setnx可能存在一些bug,即超时时间可能设置不成功!

所以当存在连接可能不够用的情况时,尽量不要使用setnx。

配置文件:

redis.onoff=true
redis.defaultExpireInSecond=900
redis.namespace=${cache_namespace}
redis.prefix=api-v3
RedisJavaClient.onoff=true
RedisJavaClient.servers=${redis_servers}
##==========================================================
redisMultiCluster.defaultExpireInSecond=900
redisMultiCluster.prefix=location-v3
redisMultiCluster.namespace=${cache_namespace}
redisMultiCluster.onoff=true
redisMultiCluster.clusters=${redis_clusters}
redisMultiCluster.route=route1:0|route2:1
redisMultiCluster.rule=com.xiaomi.weather.commons.cache.SubKeyRule
redisMultiCluster.startIndex=0
redisMultiCluster.endIndex=5 ##-------------连接池配置------------------
#最大连接数,最大资源空闲数目,最小资源空闲数目
redisMultiCluster.maxTotal=30
redisMultiCluster.maxIdle=30
redisMultiCluster.minIdle=10
#连接耗尽时,是否等待;等待时长(ms)
redisMultiCluster.blockWhenExhausted=true
redisMultiCluster.maxWaitMillis=500 #输出连接时是否检测空闲超时,回收连接检测,创建连接检测,输出连接检测,
redisMultiCluster.testWhileIdle=false
redisMultiCluster.testOnReturn=true
redisMultiCluster.testOnCreate=true
redisMultiCluster.testOnBorrow=true #(暂时不可用)资源耗尽时的处理措施0 - 抛异常,1 - 阻塞等待可用资源,2-强制创建新连接
redisMultiCluster.whenExhaustedAction=1

序列化类:

package com.xiaomi.weather.vote.webservices.util.redisCache;

import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Preconditions; /**
* Created by mi on 16-12-22.
*/
public class SerializationDefine {
public static String Object2String(Object obj) {
Preconditions.checkArgument(obj != null, "序列化对象为null");
return JSONObject.toJSONString(obj);
} public static <T> T String2Object(String str, Class<T> tClass) {
return JSONObject.parseObject(str, tClass);
}
}

工具类第二版,修复删除key,而key不存在时报异常的bug;

package com.xiaomi.weather.vote.webservices.util.redisCache;

import com.google.common.base.Strings;
import org.apache.log4j.Logger;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig; import java.io.InputStream;
import java.util.*; /**
* Created by mi on 16-12-22.
*/
public class RedisClusterClient {
private static final Logger logger = Logger.getLogger(RedisClusterClient.class);
private static String isOn = "true"; // 是否启用缓存
private static JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); // 配置信息
public JedisCluster jedisCluster = null;
Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>(); public static RedisClusterClient redisClusterClient = new RedisClusterClient(); public RedisClusterClient() {
init();
} public static RedisClusterClient getInsance() {
if (redisClusterClient != null) {
return redisClusterClient;
} else {
redisClusterClient = new RedisClusterClient();
return redisClusterClient;
}
} public boolean init() {
try {
// 读取配置文件
InputStream path = RedisClusterClient.class.getClassLoader().getResourceAsStream("cache.properties");
Properties pros = new Properties();
pros.load(path);
this.isOn = pros.getProperty("redis.onoff", "true");// 默认开启缓存
if (this.isOn.equals("false")) {// 未开启缓存
return false;
} //
String servers = pros.getProperty("redisMultiCluster.clusters", null);
if (Strings.isNullOrEmpty(servers)) {
logger.error("RedisJavaClient.servers 配置错误; in file:cache.properties");
this.isOn = "false";
return false;
}
String[] hostAndPorts = servers.split("\\|");
for (int i = 0; i < hostAndPorts.length; i++) {
String hostAndPort = hostAndPorts[i];
if (!hostAndPort.contains(":")) {
return false;
}
jedisClusterNodes.add(new HostAndPort(hostAndPort.split(":")[0], Integer.parseInt(hostAndPort.split(":")[1])));
}
try {
jedisPoolConfig.setMaxTotal(Integer.parseInt(pros.getProperty("redisMultiCluster.maxTotal", "8")));
jedisPoolConfig.setMaxIdle(Integer.parseInt(pros.getProperty("redisMultiCluster.maxIdle", "8")));
jedisPoolConfig.setMinIdle(Integer.parseInt(pros.getProperty("redisMultiCluster.minIdle", "0")));
jedisPoolConfig
.setBlockWhenExhausted(Boolean.parseBoolean(pros.getProperty("redisMultiCluster.blockWhenExhausted", "true")));
jedisPoolConfig.setMaxWaitMillis(Integer.parseInt(pros.getProperty("redisMultiCluster.maxWaitMillis", "true")));
jedisPoolConfig.setTestOnBorrow(Boolean.parseBoolean(pros.getProperty("redisMultiCluster.testOnBorrow", "true")));
jedisPoolConfig.setTestOnCreate(Boolean.parseBoolean(pros.getProperty("redisMultiCluster.testOnCreate", "true")));
jedisPoolConfig.setTestOnReturn(Boolean.parseBoolean(pros.getProperty("redisMultiCluster.testOnReturn", "true")));
jedisPoolConfig.setTestWhileIdle(Boolean.parseBoolean(pros.getProperty("redisMultiCluster.testWhileIdle", "false"))); } catch (Exception e) {
logger.error("{未知异常}", e);
}
jedisCluster = new JedisCluster(jedisClusterNodes, jedisPoolConfig);
logger.info("缓存初始化成功");
path.close();
return true;
} catch (Exception e) {
logger.error("{缓存初始化错误}", e);
this.isOn = "false";
}
return false;
} public boolean setnx(String key, String value, int expireTime) {
if (!isOn.equals("true")) {
logger.info("缓存未开启");
return false;
}
try {
Long setSuccess = jedisCluster.setnx(key, value);
if (setSuccess == 1) {//写入成功
if (1 == jedisCluster.expire(key, expireTime)) {
return true;
} else {
this.deleteKey(key);
return false;
}
} else {
return false;
}
} catch (Exception e) {
try {
this.deleteKey(key);
} catch (Exception ex) {
logger.error("删除key异常:key = " + key);
}
logger.error("{}", e);
}
return false;
} public boolean set(String key, String value, int expireTime) {
if (!isOn.equals("true")) {
logger.info("缓存未开启");
return false;
}
try {
jedisCluster.setex(key, expireTime, value);
return true;
} catch (Exception e) {
logger.error("{}", e);
}
return false;
} public String get(String key) {
if (!isOn.equals("true")) {
logger.info("缓存未开启");
return "";
}
try {
return jedisCluster.get(key);
} catch (Exception e) {
logger.error("{}", e);
}
return null;
} public <T> boolean setList(String key, List<T> list, Class<T> tClass, int expireTime) {
if (!isOn.equals("true")) {
logger.info("缓存未开启");
return false;
}
try {
if (this.setnx(key + "Lock", "true", expireTime)) {
this.deleteKey(key);
for (T t : list) {
jedisCluster.rpush(key, SerializationDefine.Object2String(t));
}
if (1 == jedisCluster.expire(key, expireTime)) {
return true;
} else {
this.deleteKey(key);
return false;
}
}
return true;
} catch (Exception e) {
logger.error("{}", e);
}
return false;
} public <T> List<T> getList(String key, Class<T> tClass) {
if (!isOn.equals("true")) {
logger.info("缓存未开启");
return null;
}
try {
List<T> tList = new ArrayList<T>();
List<String> strList = jedisCluster.lrange(key, 0L, -1L);
for (String str : strList) {
tList.add(SerializationDefine.String2Object(str, tClass));
} return tList.size() == 0 ? null : tList;
} catch (Exception e) {
logger.error("{}", e);
return null;
}
} public <T> boolean setMap(String key, Map<String, T> map, Class<T> tClass, int expireTime) {
if (!isOn.equals("true")) {
logger.info("缓存未开启");
return false;
}
Map<String, String> catchMap = new HashMap<String, String>();
try {
if (this.setnx(key + "Lock", "true", expireTime)) {
this.deleteKey(key);
for (Map.Entry<String, T> entry : map.entrySet()) {
catchMap.put(entry.getKey(), SerializationDefine.Object2String(entry.getValue()));
}
jedisCluster.hmset(key, catchMap);
if (1 == jedisCluster.expire(key, expireTime)) {
return true;
} else {
this.deleteKey(key);
return false;
} }
} catch (Exception e) {
logger.error("{严重异常}", e);
}
return true;
} public <T> Map<String, T> getMap(String key, Class<T> tClass) {
if (!isOn.equals("true")) {
logger.info("缓存未开启");
return null;
}
try {
Map<String, String> catchMap = jedisCluster.hgetAll(key);
Map<String, T> retMap = new HashMap<String, T>();
for (Map.Entry<String, String> entry : catchMap.entrySet()) {
retMap.put(entry.getKey(), SerializationDefine.String2Object(entry.getValue(), tClass));
}
return retMap;
} catch (Exception e) {
logger.error("{}", e);
return null;
} } public boolean deleteKey(String key) throws Exception {
if (!isOn.equals("true")) {
logger.info("缓存未开启");
return false;
}
try {
if (!this.isExist(key)) {//key不存在
return true;
}
if (1 == jedisCluster.del(key)) {
return true;
} else {
throw new Exception("redis异常,删除key失败:method = deleteKey; key = " + key);
}
} catch (Exception e) {
logger.error("{严重异常}", e);
throw new Exception("redis异常,删除key失败:method = deleteKey; key = " + key);
}
} /**
* 加1操作
*
* @param key
* @return
*/
public boolean incr(String key) {
if (!isOn.equals("true")) {
logger.info("缓存未开启");
return false;
}
try {
jedisCluster.incr(key);
return true;
} catch (Exception e) {
logger.error("{}", e);
return false;
}
} /**
* 减1操作
*
* @param key
* @return
*/
public boolean decr(String key) {
if (!isOn.equals("true")) {
logger.info("缓存未开启");
return false;
}
try {
jedisCluster.decr(key);
return true;
} catch (Exception e) {
logger.error("{}", e);
return false;
}
} /**
* 判断是否已缓存
*
* @param key
* @return
*/
public boolean isExist(String key) throws Exception {
if (!isOn.equals("true")) {
logger.info("缓存未开启");
return false;
}
try {
return jedisCluster.exists(key);
} catch (Exception e) {
logger.error("{严重异常}判断key是否存在发生异常... ... key = " + key, e);
throw new Exception("{严重异常}判断key是否存在发生异常... ...key = " + key);
}
} public static void main(String[] arges) {
try {
System.out.println(RedisClusterClient.getInsance().jedisCluster.del("panpanpan"));
} catch (Exception e) {
e.printStackTrace();
} }
}

redis集群使用Java工具类(Java jedis集群工具类)的更多相关文章

  1. 编写Spark的WordCount程序并提交到集群运行[含scala和java两个版本]

    编写Spark的WordCount程序并提交到集群运行[含scala和java两个版本] 1. 开发环境 Jdk 1.7.0_72 Maven 3.2.1 Scala 2.10.6 Spark 1.6 ...

  2. 005-guava 集合-集合工具类-java.util.Collections中未包含的集合工具[Maps,Lists,Sets],Iterables、Multisets、Multimaps、Tables

    一.概述 工具类与特定集合接口的对应关系归纳如下: 集合接口 属于JDK还是Guava 对应的Guava工具类 Collection JDK Collections2:不要和java.util.Col ...

  3. Java集合框架(六)—— Collections工具类

    操作集合的工具类Collections Java提供了一个操作Set.List和Map等集合的工具类:Collections,该工具类里提供了大量方法对集合元素进行排序.查询和修改等操作,还提供了将集 ...

  4. java调用kettle的job和transfer工具类

    package com.woaiyitiaocai.util; import java.util.Map; import java.util.UUID; import org.apache.log4j ...

  5. Java学习笔记 -- Java定时调度工具Timer类

    1 关于 (时间宝贵的小姐姐请跳过) 本教程是基于Java定时任务调度工具详解之Timer篇的学习笔记. 什么是定时任务调度 基于给定的时间点,给定的时间间隔或者给定的执行次数自动执行的任务. 在Ja ...

  6. JavaSE-基础语法(二)-系统类(java.lang.*)和工具类(java.util.*)

    系统类(java.lang.*)和工具类(java.util.*) 一.系统类(java.lang.*) 这个包下包含java语言的核心类,如String.Math.System和Thread类等,使 ...

  7. Java+大数据开发——Hadoop集群环境搭建(一)

    1集群简介 HADOOP集群具体来说包含两个集群:HDFS集群和YARN集群,两者逻辑上分离,但物理上常在一起 HDFS集群: 负责海量数据的存储,集群中的角色主要有 NameNode / DataN ...

  8. 反射工具类.提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class,被AOP过的真实类等工具函数.java

    import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import org.ap ...

  9. 4 kafka集群部署及kafka生产者java客户端编程 + kafka消费者java客户端编程

    本博文的主要内容有   kafka的单机模式部署 kafka的分布式模式部署 生产者java客户端编程 消费者java客户端编程 运行kafka ,需要依赖 zookeeper,你可以使用已有的 zo ...

  10. 开发工具、Object类(java基础知识十一)

    1.常见开发工具介绍 * A:操作系统自带的记事本软件 * B:高级记事本软件 * C:集成开发环境 IDE     * (Integrated Development Environment) *  ...

随机推荐

  1. LIS(模板)

    记录一下,O(nlgn)的算法求LIS //HHH #include <iostream> #include <stdio.h> #include <string.h&g ...

  2. DataTable数据筛选

    DataView view = newDt.DefaultView;view.Sort = "Description asc,replyEnd desc";DataTable ta ...

  3. 截取字符(pos,copy,Leftstr,MidStr,RightStr)以逗号为准把字符串拆分,判断字符串是否有数字、字母(大小写), 去掉字符串空格

    1.copy(a,b,c) 举个例子: str := “123456”;str1 := Copy(Str,2,3);结果就是 str1 等于 234.Copy有3个参数,第一个是你要处理的字符串,第二 ...

  4. 九度OJ 1360:乐透之猜数游戏 (递归)

    时间限制:2 秒 内存限制:32 兆 特殊判题:否 提交:955 解决:261 题目描述: 六一儿童节到了,YZ买了很多丰厚的礼品,准备奖励给JOBDU里辛劳的员工.为了增添一点趣味性,他还准备了一些 ...

  5. IOS自动布局的Problem

    今天为做一个小小的footerView我的心脏差点气出来... 第一步 新建一个view xib文件 第二步 新建一个UIview的类 第三步 在UIview中间放一个Lable,添加约束,水平垂直居 ...

  6. MySql最左前缀原则

    简单整理记录下,之前一直都没有关注过这个问题 最左前缀原则:顾名思义是最左优先,以最左边的为起点任何连续的索引都能匹配上, 注:如果第一个字段是范围查询需要单独建一个索引 注:在创建多列索引时,要根据 ...

  7. Django报:builtin_function_or_method' object is not iterable

    def detail(request,hero_id): hero=models.HeroInfo.objects.get(id=hero_id) return render_to_response( ...

  8. Python 是怎么火起来的?

    Python 之父 Guido 正在设计 Python 语言,结果家里突然潜入一条大蟒蛇,一番激烈斗争,大蟒蛇把 Guido 叔生吞进肚,并洋洋自得:So Who is Guido Van Rossu ...

  9. Spring 单例

    我们知道 Web 容器本身就是多线程的,Web 容器为一个 Http 请求创建一个独立的线程,所以由此请求所牵涉到的 Spring 容器中的 Bean 也是运行于多线程的环境下.在绝大多数情况下,Sp ...

  10. Geforce experience报错:something went wrong try restarting geforce

    右键计算机 ——>管理——> 服务和应用程序 ——>服务中