1. 前言:
在老项目基础上去做redis集群,是一件很痛苦的事情,必须把对应jar和配置都一一对应好,不然都是报错的异常,此次是基于Spring低版本嵌入Redis集群的一些经验,各位看官可以参考借鉴。
2. 项目jar依赖版本
spring-webmvc-3.2.1.RELEASE.jar(spring其他依赖也是此版本)
commons-pool2-2.2.jar
jedis-2.9.0.jar
spring-data-commons-1.8.1.RELEASE.jar
spring-data-redis-1.8.1.RELEASE.jar
3. redis.properties配置文件(此配置只支持redis集群sentinel模式)
#密码
redis.password=123456
#sentinel
spring.redis.sentinel.nodes=127.0.0.1:26379,127.0.0.1:36379
spring.redis.sentinel.master=mymaster
#spring.redis.sentinel.master=mymaster
#spring.redis.sentinel.node1.host=10.60.17.2
#spring.redis.sentinel.node2.host=10.60.17.3
#spring.redis.sentinel.node1.port=26379
#spring.redis.sentinel.node2.port=26379
#sentinel
4. applicationContext-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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:cache="http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"
>
<!-- jedis 配置-->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig" >
<!--最大空闲数-->
<property name="maxIdle" value="500" />
<!--最大连接数-->
<property name="maxTotal" value="1000" />
<!--最大建立连接等待时间-->
<property name="maxWaitMillis" value="-1" />
<!--是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个-->
<property name="testOnBorrow" value="true" />
</bean >
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:redis.properties" />
</bean>
<bean id="resourcePropertySource" class="org.springframework.core.io.support.ResourcePropertySource">
<constructor-arg name="name" value="redis.properties"/>
<constructor-arg name="resource" value="classpath:redis.properties"/>
</bean>
<!-- redis的sentinel哨兵配置 -->
<bean id="sentinelConfiguration"
class="org.springframework.data.redis.connection.RedisSentinelConfiguration">
<constructor-arg name="propertySource" ref="resourcePropertySource"/>
</bean>
<!-- redis服务器中心 -->
<bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >
<constructor-arg name="poolConfig" ref="poolConfig"/>
<constructor-arg index="0" type="org.springframework.data.redis.connection.RedisSentinelConfiguration" ref="sentinelConfiguration" />
<property name="password" value="${redis.password}" />
<property name="timeout" value="10000" ></property>
</bean >
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" >
<property name="connectionFactory" ref="connectionFactory" />
<!--如果不配置Serializer,那么存储的时候缺省使用String,如果用User类型存储,那么会提示错误User can't cast to String!! -->
<property name="keySerializer" >
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="valueSerializer" >
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
</property>
<property name="hashKeySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
<property name="hashValueSerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
</property>
</bean >
</beans>
我这里使用的是配置文件注入集群配置,如果使用constructor-arg构造器注入会有注入异常。
- web.xml配置
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext-redis.xml</param-value>
</context-param>
6. 重写spring核心类
spring版本过低,不兼容redis高版本,初始化会报错,此方法是spring4.2X版本以上才有,所以需要重写两个spring类。
package org.springframework.core.serializer;
/**
* @Auther: cxz
* @Date: 2021/12/21 15:08
* @Description:
*/
import org.springframework.core.ConfigurableObjectInputStream;
import org.springframework.core.NestedIOException;
import java.io.IOException;
import java.io.InputStream;
/**
* spring低版本不兼容redis高版本,需要重写类
* @author cxz
*
*/
public class DefaultDeserializer implements Deserializer<Object> {
private final ClassLoader classLoader;
public DefaultDeserializer() {
this.classLoader = null;
}
public DefaultDeserializer(ClassLoader classLoader) {
this.classLoader = classLoader;
}
public Object deserialize(InputStream inputStream) throws IOException {
ConfigurableObjectInputStream objectInputStream = new ConfigurableObjectInputStream(inputStream, this.classLoader);
try {
return objectInputStream.readObject();
} catch (ClassNotFoundException var4) {
throw new NestedIOException("Failed to deserialize object type", var4);
}
}
}
/**
* @Auther: cxz
* @Date: 2021/12/21 15:07
* @Description:
*/
package org.springframework.core.serializer.support;
import java.io.ByteArrayInputStream;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.serializer.DefaultDeserializer;
import org.springframework.core.serializer.Deserializer;
import org.springframework.util.Assert;
/**
* spring低版本不兼容redis高版本,需要重写类
* @author cxz
*
*/
public class DeserializingConverter implements Converter<byte[], Object> {
private final Deserializer<Object> deserializer;
public DeserializingConverter() {
this.deserializer = new DefaultDeserializer();
}
public DeserializingConverter(ClassLoader classLoader) {
this.deserializer = new DefaultDeserializer(classLoader);
}
public DeserializingConverter(Deserializer<Object> deserializer) {
Assert.notNull(deserializer, "Deserializer must not be null");
this.deserializer = deserializer;
}
public Object convert(byte[] source) {
ByteArrayInputStream byteStream = new ByteArrayInputStream(source);
try {
return this.deserializer.deserialize(byteStream);
} catch (Throwable var4) {
throw new SerializationFailedException("Failed to deserialize payload. Is the byte array a result of corresponding serialization for " + this.deserializer.getClass().getSimpleName() + "?", var4);
}
}
}
这里是引用
7. redisTemplate模板使用
8. 总结
在此次配置redis集群上踩过太多坑,最重要的是Spring低版本不兼容的问题,建议有能力的还是升级Spring版本吧。
走过路过,点赞收藏起来~