Spring+Redis集群部署方案
建议和我使用的版本相同,不然会出现各种各样的错误
spring-*:4.2.8 redis-data-redis:1.8.1 redis.clients:2.9.0 commons-pool2:2.4.3
加载的配置文件(部分)
<!-- jedis依赖 开始整合redis缓存 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.8.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.4.3</version>
</dependency>
redis-spring.xml 需要在web.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"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:util="http://www.springframework.org/schema/util"
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
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<!-- 引入配置文件 -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:redis.properties</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="true" />
</bean>
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!--最大空闲数-->
<property name="maxIdle" value="${redis.pool.maxIdle}"/>
<property name="maxTotal" value="${redis.pool.maxTotal}"/>
<!--最大建立连接等待时间-->
<property name="maxWaitMillis" value="${redis.pool.maxWaitMillis}"/>
<!--是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个-->
<property name="testOnBorrow" value="${redis.pool.testOnBorrow}"/>
<property name="testOnReturn" value="${redis.pool.testOnReturn}"/>
</bean>
<!-- *************************** -->
<!--多节点配置,配置RedisClusterConfiguration-->
<bean id="redisClusterConfiguration" class="org.springframework.data.redis.connection.RedisClusterConfiguration">
<property name="maxRedirects" value="6"></property>
<property name="clusterNodes">
<set>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="127.0.0.1"/>
<constructor-arg name="port" value="9000"/>
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="127.0.0.1"/>
<constructor-arg name="port" value="9001"/>
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="127.0.0.1"/>
<constructor-arg name="port" value="9002"/>
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="127.0.0.1"/>
<constructor-arg name="port" value="9003"/>
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="127.0.0.1"/>
<constructor-arg name="port" value="9004"/>
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="127.0.0.1"/>
<constructor-arg name="port" value="9005"/>
</bean>
</set>
</property>
</bean>
<!-- *************************** -->
<!-- 连接池配置,类似数据库连接池 -->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<!-- 这里注释的为单节点
<property name="hostName" value="${redis.master.ip}"/>
<property name="port" value="${redis.master.port}"/>
-->
<property name="poolConfig" ref="jedisPoolConfig"/>
<constructor-arg name="clusterConfig" ref="redisClusterConfiguration"/>
</bean>
<!--如果不配置Serializer,那么存储的时候缺省使用String,如果用User类型存储,那么会提示错误User can't cast to String!! -->
<bean id="redisKeySerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
<bean id="redisValueSerializer" class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
<!-- spring data提供redis模板 -->
<!-- 在学习redis的时候,我们一般会用到spring data来将redis整合,我们需要用到配置文件,在过程中会出现redis的键乱码\ xac \ xed \ x00 \ x05t \ x00 \ tb!
其实只要改变下配置文件,下面是全部配置文件,注掉的是会乱码的配置 -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory"/>
<property name="keySerializer" ref="redisKeySerializer"/>
<property name="hashKeySerializer" ref="redisKeySerializer"/>
<property name="valueSerializer" ref="redisValueSerializer"/>
<property name="hashValueSerializer" ref="redisValueSerializer"/>
</bean>
<util:properties id="redisExpires" location="classpath:rediscustom.properties"/>
<!-- 使用RedisCacheManger作为cachemange实现类 ,需要将下面的id=aaa改为id=CacheManager-->
<bean id="aaa" class="org.springframework.data.redis.cache.RedisCacheManager">
<constructor-arg index="0" ref="redisTemplate"/>
<!-- 属性设置了全局的默认失效时间 -->
<property name="defaultExpiration" value="600"/>
<property name="usePrefix" value="true"/>
<!-- expires属性则根据map指定的key单独设置失效时间 -->
<property name="expires" ref="redisExpires"/>
<property name="CacheNames" value="content"/>
<!-- expires属性则根据map指定的key单独设置失效时间
<property name="expires">
<map>
<entry key="content" value="30"/>
</map>
</property>
-->
</bean>
<!-- 使用(测试)simpleCacheManger作为cachemange实现类 ,需要将下面的id=aaa改为id=CacheManager-->
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<!-- 这里可以配置多个redis -->
<bean class="com.song.redis.RedisCache">
<property name="redisTemplate" ref="redisTemplate" />
<!-- name对应的名称要在类或方法的注解中使用 -->
<property name="name" value="content"/>
</bean>
<!-- 这里可以配置多个redis
<bean class="com.song.redis.RedisCache">
<property name="redisTemplate" ref="redisTemplate" />
<property name="name" value="hello"/>
</bean>
-->
</set>
</property>
</bean>
<!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 -->
<!--启用 cache 注解-->
<cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true"/>
</beans>
redis.properties
##########################
## redis缓存配置
##########################
# redis主机IP
redis.master.ip=127.0.0.1
# redis端口
redis.master.port=9001
# 密码
#redis.pass=123456
##########################
## redis连接池配置
##########################
# 最大空闲连接数
redis.pool.maxIdle=200
# 最大连接数
redis.pool.maxTotal=1024
# 获取链接最大等待毫秒
redis.pool.maxWaitMillis=1000
# 获取链接时检查有效性
redis.pool.testOnBorrow=true
redis.pool.testOnReturn=true
在redis-spring.xml 中加载的接口com.song.redis.RedisCache,使用的是的重写RedisTemple方法
package com.song.redis;
/**
* Copyright: Copyright (c) 2019 LanRu-Caifu
*
* @ClassName: RedisCache.java
* @Description: 该类的功能描述
*
* @version: v1.0.0
* @author: dongsong
* @date: 2019年7月12日 下午6:56:33
*
* Modification History:
* Date Author Version Description
*---------------------------------------------------------*
* 2019年7月12日 dongsong v1.0.0 修改原因
*/
import java.io.Serializable;
import org.apache.commons.lang3.SerializationUtils;
import org.springframework.cache.Cache;
import org.springframework.cache.support.SimpleValueWrapper;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
public class RedisCache implements Cache {
private RedisTemplate<String, Object> redisTemplate;
private String name;
@Override
public void clear() {
System.out.println("-------緩存清理------");
redisTemplate.execute(new RedisCallback<String>() {
@Override
public String doInRedis(RedisConnection connection) throws DataAccessException {
connection.flushDb();
return "ok";
}
});
}
@Override
public void evict(Object key) {
System.out.println("-------緩存刪除------");
final String keyf=key.toString();
redisTemplate.execute(new RedisCallback<Long>() {
@Override
public Long doInRedis(RedisConnection connection) throws DataAccessException {
return connection.del(keyf.getBytes());
}
});
}
@Override
public ValueWrapper get(Object key) {
System.out.println("------缓存获取-------"+key.toString());
final String keyf = key.toString();
Object object = null;
object = redisTemplate.execute(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
byte[] key = keyf.getBytes();
byte[] value = connection.get(key);
if (value == null) {
System.out.println("------缓存不存在-------");
return null;
}
return SerializationUtils.deserialize(value);
}
});
ValueWrapper obj=(object != null ? new SimpleValueWrapper(object) : null);
System.out.println("------获取到内容-------"+obj);
return obj;
}
@Override
public void put(Object key, Object value) {
System.out.println("-------加入缓存------");
System.out.println("key----:"+key);
System.out.println("key----:"+value);
final String keyString = key.toString();
final Object valuef = value;
final long liveTime = 86400;
redisTemplate.execute(new RedisCallback<Long>() {
@Override
public Long doInRedis(RedisConnection connection) throws DataAccessException {
byte[] keyb = keyString.getBytes();
byte[] valueb = SerializationUtils.serialize((Serializable) valuef);
connection.set(keyb, valueb);
if (liveTime > 0) {
connection.expire(keyb, liveTime);
}
return 1L;
}
});
}
@Override
public <T> T get(Object arg0, Class<T> arg1) {
// TODO Auto-generated method stub
return null;
}
@Override
public String getName() {
return this.name;
}
@Override
public Object getNativeCache() {
return this.redisTemplate;
}
@Override
public ValueWrapper putIfAbsent(Object arg0, Object arg1) {
// TODO Auto-generated method stub
return null;
}
public RedisTemplate<String, Object> getRedisTemplate() {
return redisTemplate;
}
public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
public void setName(String name) {
this.name = name;
}
}
使用方法:
在你需要将数据加入redis的方法上加上@Cacheable(CacheNames=“content”,key=“‘***’”)其中在使用的key必须符合EL/spEL规则。另cacheNames中的值已在redis-spring.xml中配置好。
例子
@Override
@Cacheable(cacheNames="content",key="'adminlog'")
public List<AdminLog> selectall() {
// TODO Auto-generated method stub
return adminlogmapper.selectlist();
}