redis 缓存使用,项目中有使用到了REDIS,之前同事使用的是使用SPRING方式集成,使用了配置文件,看了之后觉得不好,配置文件过于强依赖于项目,所以自己改了一下。 不依赖于项目启动,想用就用,不想用就不用。不会影响项目启动
话不多说,直接看代码。
配置文件redis.properties
#最大空闲数
redis.maxIdle=100
#最大连接数
redis.maxActive=300
#最大建立连接等待时间
redis.maxWait=1000
#客户端超时时间单位是毫秒
redis.timeout=30000
redis.maxTotal=1000
redis.minIdle=8
#明是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
redis.testOnBorrow=true
#cluster
address1=192.168.23.200:7001
address2=192.168.23.200:7002
address3=192.168.23.200:7003
address4=192.168.23.200:7004
address5=192.168.23.200:7005
address6=192.168.23.200:7006
package com.cat.common.redis;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Pattern;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;
import com.cat.common.lang.RString;
import com.cat.common.listener.REnvContent;
import com.cat.common.listener.RSystemConfig;
import com.cat.common.properties.PropertiesUtil;
public class RedisClient{
public static final int default_seconds = 300;
private static Properties properties = null;
private static RedisClient client = null;
private JedisCluster jedisCluster = null;
private RedisClient(){
try{
initRedisConfig();
}catch(Exception e){
e.printStackTrace();
}
}
public static synchronized RedisClient getInstance(){
if(null == client){
client = new RedisClient();
}
return client;
}
private void initRedisConfig()
throws Exception{
String path = RSystemConfig.Home_Path + REnvContent.Redis_Properties;
properties = PropertiesUtil.getInstance().getProperties(path);
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxIdle(Integer.parseInt(properties.getProperty("redis.maxIdle", "100")));
poolConfig.setMinIdle(Integer.parseInt(properties.getProperty("redis.minIdle", "8")));
poolConfig.setMaxTotal(Integer.parseInt(properties.getProperty("redis.maxTotal", "1000")));
poolConfig.setTestOnBorrow(Boolean.getBoolean(properties.getProperty("redis.testOnBorrow", "true")));
poolConfig.setMaxWaitMillis(Integer.parseInt(properties.getProperty("redis.maxWait", "1000")));
poolConfig.setTimeBetweenEvictionRunsMillis(Integer.parseInt(properties.getProperty("redis.timeout", "300000")));
Set<HostAndPort> nodes = new HashSet<HostAndPort>();
Pattern p = Pattern.compile("^.+[:]\\d{1,5}\\s*$");
for(Object key : properties.keySet()){
if(!((String) key).startsWith("address")){
continue;
}
String val = (String) properties.get(key);
boolean isIpPort = p.matcher(val).matches();
if(!isIpPort){
throw new IllegalArgumentException("ip 或 port 不合法");
}
String[] ipAndPort = val.split(":");
HostAndPort hap = new HostAndPort(ipAndPort[0], Integer.parseInt(ipAndPort[1]));
nodes.add(hap);
}
jedisCluster = new JedisCluster(nodes, poolConfig);//JedisCluster中默认分装好了连接池.
}
/**
* 设置指定的值,设置超时时间,时间为秒
* @param key
* @param value
* @param seconds 秒必须大于0 ,为0 时默认 300秒
*/
public boolean setStringExValue(String key,
String value,
int seconds){
if(seconds == 0){
seconds = 300;
}
if(RString.isBlank(key, value)){
return false;
}
jedisCluster.setex(key, seconds, value);
return true;
}
/**
* 设置指定的值,设置超时时间,时间为秒
* @param key
* @param value
* @param seconds 秒必须大于0 ,为0 时默认 300秒
*/
public boolean setObjExValue(String key,
Object value,
int seconds){
if(seconds == 0){
seconds = 300;
}
if(RString.isBlank(key)){
return false;
}
if(RString.isBlank(key)){
return false;
}
jedisCluster.setex(key, seconds, objectSerialiable(value));
return true;
}
/**
* 判断是否存在
* @param key
* @return
*/
public boolean isKeyExist(String key){
if(RString.isBlank(key)){
return false;
}
return jedisCluster.exists(key);
}
/**
* 返回值
* @param key
* @return
*/
public String getStringValue(String key){
return jedisCluster.get(key);
}
/**
* 返回值
* @param key
* @return
*/
public Object getObjValue(String key){
return objectDeserialization(jedisCluster.get(key));
}
/**
* 删除缓存
* @param key
*/
public void deleteValue(String key){
jedisCluster.del(key);
}
/**
* 对象序列化为字符串
* @param obj
* @return
*/
public static String objectSerialiable(Object obj){
String serStr = null;
try{
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(obj);
serStr = byteArrayOutputStream.toString("ISO-8859-1");
serStr = java.net.URLEncoder.encode(serStr, "UTF-8");
objectOutputStream.close();
byteArrayOutputStream.close();
}catch(UnsupportedEncodingException e){
//_logger.error(e);
}catch(IOException e){
//_logger.error(e);
}
return serStr;
}
/**
* 字符串反序列化为对象
* @param serStr
* @return
*/
public static Object objectDeserialization(String serStr){
Object newObj = null;
try{
String redStr = java.net.URLDecoder.decode(serStr, "UTF-8");
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(redStr.getBytes("ISO-8859-1"));
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
newObj = objectInputStream.readObject();
objectInputStream.close();
byteArrayInputStream.close();
}catch(UnsupportedEncodingException e){
//_logger.error(e);
}catch(ClassNotFoundException e){
//_logger.error(e);
}catch(IOException e){
//_logger.error(e);
}
return newObj;
}
}
package com.cat.common.redis;
public class RRedisContent{
public class ActDic{
/**
* 数据字典的缓存KEY
*/
public static final String Act_Dic_list = "act_dic_list";
}
public class ActTgActivity{
/**
* 数据字典的缓存KEY
*/
public static final String Act_Activity_list = "act_activity_list";
}
public class ActTgChannel{
/**
* 数据字典的缓存KEY
*/
public static final String Act_Channel_list = "act_channel_list";
}
}
大多数人选择redis 和memcahe 的时候,都会看到网上的资料说,redis支持的字段类型多,巴拉巴拉的什么的,所以都会选择redis,当真正的项目使用中,顶多使用key-value形式的方式。完全用不到redis的真正的用法。但是memcahe在key-value 形式的用法上,我个人觉得是 比redis要好用多了的。所以在选择缓存的时候要先评估自己的项目需要使用是什么程度。 如果你的项目都是key-value,我建议使用 memcahe。 在使用redis 存储key-value形式的时候,把对象序列化,还要转换为字符串,这是一个很恶心的动作。 但是memcahe,就很好,只要你的对象实现了序列化,就可以直接存储。