今天做redis主从集群 单节点就废弃不用了 写个博客 记录一下单节点的用法
此案例经过实际考验,当初使用spring-data-redis是因为当交易量达到一小时30万笔左右时,jedis的连接池直接嵌入spring中老是有丢失连接和拿不到连接的错误,后来整合完之后,就没有了类似情况,这个还是蛮好用的
1 spring-redis.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd "
default-autowire="byName">
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 连接池中最大连接数。高版本:maxTotal,低版本:maxActive -->
<property name="maxTotal" value="${redis.maxTotal}" />
<!-- 连接池中最大空闲的连接数. -->
<property name="maxIdle" value="${redis.maxIdle}" />
<!-- 连接池中最少空闲的连接数. -->
<property name="minIdle" value="${redis.minIdle}" />
<!-- 当连接池资源耗尽时,调用者最大阻塞的时间,超时将跑出异常。单位,毫秒数;默认为-1.表示永不超时。高版本:maxWaitMillis,低版本:maxWait -->
<property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
<!-- 连接空闲的最小时间,达到此值后空闲连接将可能会被移除。负值(-1)表示不移除. -->
<property name="minEvictableIdleTimeMillis" value="${redis.minEvictableIdleTimeMillis}" />
<!-- 对于“空闲链接”检测线程而言,每次检测的链接资源的个数。默认为3 -->
<property name="numTestsPerEvictionRun" value="${redis.numTestsPerEvictionRun}" />
<!-- “空闲链接”检测线程,检测的周期,毫秒数。如果为负值,表示不运行“检测线程”。默认为-1. -->
<property name="timeBetweenEvictionRunsMillis" value="${redis.timeBetweenEvictionRunsMillis}" />
<!-- testOnBorrow:向调用者输出“链接”资源时,是否检测是有有效,如果无效则从连接池中移除,并尝试获取继续获取。默认为false。建议保持默认值. -->
<!-- testOnReturn:向连接池“归还”链接时,是否检测“链接”对象的有效性。默认为false。建议保持默认值. -->
<!-- testWhileIdle:向调用者输出“链接”对象时,是否检测它的空闲超时;默认为false。如果“链接”空闲超时,将会被移除。建议保持默认值. -->
<!-- whenExhaustedAction:当“连接池”中active数量达到阀值时,即“链接”资源耗尽时,连接池需要采取的手段, 默认为1(0:抛出异常。1:阻塞,直到有可用链接资源。2:强制创建新的链接资源) -->
</bean>
<bean id="jedisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
destroy-method="destroy">
<!-- 连接池配置. -->
<property name="poolConfig" ref="jedisPoolConfig"></property>
<!-- Redis服务主机. -->
<property name="hostName" value="${redis.hostName}"></property>
<!-- Redis服务端口号. -->
<property name="port" value="${redis.port}"></property>
<!-- Redis服务连接密码. -->
<!-- <property name="password" value="${redis.password}" /> -->
<!-- 连超时设置. -->
<property name="timeout" value="${redis.timeout}"></property>
<!-- 是否使用连接池. -->
<property name="usePool" value="${redis.usePool}"></property>
</bean>
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory"></property>
<property name="keySerializer">
<bean
class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="valueSerializer">
<!-- <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"
/> -->
<bean
class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
</property>
<property name="hashKeySerializer">
<bean
class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="hashValueSerializer">
<bean
class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
</property>
</bean>
<!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 -->
<cache:annotation-driven cache-manager="cacheManager" />
<!-- spring自己的缓存管理器,这里定义了缓存位置名称 ,即注解中的value -->
<bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
<constructor-arg ref="redisTemplate" />
<property name="usePrefix" value="true" />
<property name="defaultExpiration" value="3600" />
<property name="expires">
<map>
<entry key="xxx:xxx:id" value="86400"/>
</map>
</property>
</bean>
<bean id="jedisHelper" class="com.xxx.JedisHelper">
<property name="redisTemplate" ref="redisTemplate" />
</bean>
</beans>
配置属性
redis.hostName=xxx.xx.xx.x
redis.port=6379
redis.timeout=20000
redis.usePool=true
redis.maxTotal=8
redis.maxIdle=6
redis.minIdle=1
redis.maxWaitMillis=5000
redis.minEvictableIdleTimeMillis=300000
redis.numTestsPerEvictionRun=3
redis.timeBetweenEvictionRunsMillis=60000
2.pom.xml 配置
<!-- spring redis -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.7.0.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
3. JedisHelper.java
package com.xxx.u01;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.apache.log4j.Logger;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.BoundZSetOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
/**
*
* @AUTHOR dayu
* @DATE 2017年4月20日 上午9:30:00
* @Description JRedis缓存帮助类,对Spring RedisTemplate的封装
*/
public class JedisHelper {
private static Logger logger = Logger.getLogger(JedisHelper.class);
private static RedisTemplate<Serializable, Object> redisTemplate;
public static RedisTemplate<Serializable, Object> getRedisTemplate() {
return redisTemplate;
}
public static void setRedisTemplate(RedisTemplate<Serializable, Object> redisTemplate) {
JedisHelper.redisTemplate = redisTemplate;
}
/**
* 批量删除对应的value
*
* @param keys
*/
public static void remove(final String... keys) {
for (String key : keys) {
remove(key);
}
}
/**
* 正则批量删除key 例:h?llo matches hello, hallo
*
* @param pattern
*/
public static void removePattern(final String pattern) {
Set<Serializable> keys = redisTemplate.keys(pattern);
if (keys.size() > 0)
redisTemplate.delete(keys);
}
/**
* 正则获取多个缓存key 例:h?llo matches hello, hallo
*
* @param pattern
*/
public static Set<Serializable> patternKeys(final String pattern) {
Set<Serializable> keys = redisTemplate.keys(pattern);
return keys;
}
/**
* 正则key获取多个缓存
*
* @param pattern
* @return 返回Set >-String 集合
*/
public static Set<String> patternKeysIsStr(final String pattern) {
Set<Serializable> keys = redisTemplate.keys(pattern);
Set<String> dataSet = new HashSet<>();
for (Serializable obj : keys) {
dataSet.add(obj.toString());
}
return dataSet;
}
/**
* 删除对应的value
*
* @param key
*/
public static void remove(final String key) {
if (exists(key)) {
redisTemplate.delete(key);
}
}
/**
* 判断缓存中是否有对应的value
*
* @param key
* @return
*/
public static boolean exists(final String key) {
return redisTemplate.hasKey(key);
}
/**
* 读取缓存
*
* @param key
* @return
*/
public static Object getObject(final String key) {
Object result = null;
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
result = operations.get(key);
return result;
}
/**
* 写入缓存
*
* @param key
* @param value
* @return
*/
public static boolean setObject(final String key, Object value) {
boolean result = false;
try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
operations.set(key, value);
result = true;
} catch (Exception e) {
logger.warn("setObject 返回异常 " + e.getMessage());
}
return result;
}
/**
* 写入缓存设置并设置时间 时间单位(秒)
*
* @param key
* @param value
* @return
*/
public static boolean setObjectAndExpire(final String key, Object value, Long expireTime) {
boolean result = false;
try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
operations.set(key, value);
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
result = true;
} catch (Exception e) {
logger.warn("setObjectAndExpire 返回异常 " + e.getMessage());
}
return result;
}
/**
* 清空redis 所有数据
*
* @return 成功返回 ok
*/
public static String flushDB() {
return (String) redisTemplate.execute(new RedisCallback<Object>() {
public String doInRedis(RedisConnection connection) throws DataAccessException {
connection.flushDb();
return "ok";
}
});
}
/**
* @return 查看redis里有多少数据
*/
public static long dbSize() {
return (long) redisTemplate.execute(new RedisCallback<Object>() {
public Long doInRedis(RedisConnection connection) throws DataAccessException {
return connection.dbSize();
}
});
}
/**
* 检查是否连接成功
*
* @return 成功则返回 PONG 失败什么都不会留下
*/
public static String ping() {
return (String) redisTemplate.execute(new RedisCallback<Object>() {
public String doInRedis(RedisConnection connection) throws DataAccessException {
return connection.ping();
}
});
}
}
4.spring中redis缓存应用
@Cacheable(value = "xxx:xxx:id", key = "#id")//更多应用参考官方文档
public List<xxx> find01_filterId(String id) {
xxx qry = new xxx();
qry.setParam(id);
List<xxx> lst = queryList(qry);
return lst;
}//method
5,在applicationContext.xml中应用 spring-redis.xml
6,测试JedisCacheablePlusTests.java
package com.test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.xxManager;
import com.xxxConfig;
import com.xxx.JedisHelper;
import junit.framework.Assert;
/**
*
* @AUTHOR dayu
* @DATE 2017年4月20日 上午9:35:00
* @Description JedisHelper的测试类
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "/applicationContext.xml" })
public class JedisCacheablePlusTests {
@Autowired
private xxManager xxManager;
@Test
public void test4Cacheable() {
List<xxxConfig> list=xxManager.find01_filterId(id);
Assert.assertEquals(2, list.size());
}
@Test
public void test4setObject() {
System.out.println("test4setObject");
JedisHelper.setObject("JedisCacheablePlusTests1", "你想干啥");
Map<String, Object> map1 = new HashMap<String, Object>();
map1.put("key1", 1);
map1.put("key2", "tesat");
map1.put("key3", "中文");
map1.put("key4", "http://www.baidu.com");
JedisHelper.setObject("JedisCacheablePlusTests2", map1);
List<String> list1 = new ArrayList<String>();
list1.add("eee1");
list1.add("eee2");
list1.add("eee3");
list1.add("eee4呵呵");
JedisHelper.setObject("JedisCacheablePlusTests3", list1);
}
}
注意:请根据实际情况修改代码,保证代码运行。