Spring3X版本 redis集群解决方案

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构造器注入会有注入异常。

  1. 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模板使用
redis模板使用
8. 总结
在此次配置redis集群上踩过太多坑,最重要的是Spring低版本不兼容的问题,建议有能力的还是升级Spring版本吧。

走过路过,点赞收藏起来~

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值