全网小程序源码分享

Spring + Jedis集成Redis(集群redis数据库)

前段时间说过单例redis数据库的方法,但是生成环境一般不会使用,基本上都是集群redis数据库,所以这里说说集群redis的代码。

1、pom.xml引入jar

<!--Redis-->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.8.0</version>
</dependency>

 2、在redis.properties文件里面配置redis的地址和端口(ps:这个属性文件只配置redis集群的地址和端口,方便以后扩展)

address1=redis服务器IP:6379
address2=redis服务器IP:6379
address3=redis服务器IP:6379
address4=redis服务器IP:6379
address5=redis服务器IP:6379
address6=redis服务器IP:6379

3、新建一个属性文件redisconfig.properties配置其他的redis集群环境

#客户端超时时间单位是毫秒
redis.timeout=300000
#最大连接数
redis.maxActive=300
#最小空闲数
redis.minIdle=8
#最大空闲数
redis.maxIdle=100
#最大建立连接等待时间
redis.maxWaitMillis=1000
#redis集群单位数
redis.maxRedirections=6    //这里和你的redis数据库个数一样

4、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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <!-- 读取配置文件信息 -->
    <context:property-placeholder ignore-unresolvable="true" location="classpath:*.properties"/>

    <!-- jedis cluster config -->
    <bean name="genericObjectPoolConfig" class="org.apache.commons.pool2.impl.GenericObjectPoolConfig" >
        <property name="maxTotal" value="${redis.maxActive}" />
        <property name="minIdle" value="${redis.minIdle}" />
        <property name="maxIdle" value="${redis.maxIdle}" />
        <property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
    </bean>

    <bean id="jedisCluster" class="com.topteam.redis.JedisClusterFactory">
        <property name="addressConfig" value="classpath:redis.properties"/>
        <property name="addressKeyPrefix" value="address" />

        <property name="timeout" value="${redis.timeout}" />
        <property name="maxRedirections" value="${redis.maxRedirections}" />
        <property name="genericObjectPoolConfig" ref="genericObjectPoolConfig" />
    </bean>
</beans>

5、序列化和反序列化工具代码

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 * 序列化和反序列化工具
 */
public class SerializerUtil {

    /**
     * 序列化
     * @param object
     * @return
     */
    public static byte[] serializeObj(Object object) {
        ObjectOutputStream oos = null;
        ByteArrayOutputStream baos = null;
        try {
            baos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(baos);
            oos.writeObject(object);
            byte[] bytes = baos.toByteArray();
            return bytes;
        } catch (Exception e) {
            throw new RuntimeException("序列化失败!", e);
        }
    }

    /**
     * 反序列化
     * @param bytes
     * @return
     */
    public static Object deserializeObj(byte[] bytes) {
        if (bytes == null){
            return null;
        }
        ByteArrayInputStream bais = null;
        try {
            bais = new ByteArrayInputStream(bytes);
            ObjectInputStream ois = new ObjectInputStream(bais);
            return ois.readObject();
        } catch (Exception e) {
            throw new RuntimeException("反序列化失败!", e);
        }
    }
}

6、自己新建一个JedisClusterFactory.java集群工厂类

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Pattern;


/**
 * JedisCluster集群工厂类
 */
public class JedisClusterFactory implements FactoryBean<JedisCluster>, InitializingBean {
    private Resource addressConfig;
    private String addressKeyPrefix;
    private JedisCluster jedisCluster;
    private Integer timeout;
    private Integer maxRedirections;
    private GenericObjectPoolConfig genericObjectPoolConfig;
    private Pattern p = Pattern.compile("^.+[:]\\d{1,5}\\s*$");

    public JedisClusterFactory() {
    }

    public JedisCluster getObject() throws Exception {
        return this.jedisCluster;
    }

    public Class<? extends JedisCluster> getObjectType() {
        return this.jedisCluster != null?this.jedisCluster.getClass():JedisCluster.class;
    }

    public boolean isSingleton() {
        return true;
    }

    private Set<HostAndPort> parseHostAndPort() throws Exception {
        try {
            Properties ex = new Properties();
            ex.load(this.addressConfig.getInputStream());
            HashSet haps = new HashSet();
            Iterator i$ = ex.keySet().iterator();

            while(i$.hasNext()) {
                Object key = i$.next();
                if(((String)key).startsWith(this.addressKeyPrefix)) {
                    String val = (String)ex.get(key);
                    boolean isIpPort = this.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]));
                    haps.add(hap);
                }
            }

            return haps;
        } catch (IllegalArgumentException var9) {
            throw var9;
        } catch (Exception var10) {
            throw new Exception("解析 jedis 配置文件失败", var10);
        }
    }

    public void afterPropertiesSet() throws Exception {
        Set haps = this.parseHostAndPort();
        this.jedisCluster = new JedisCluster(haps, this.timeout.intValue(), this.maxRedirections.intValue(), this.genericObjectPoolConfig);
    }

    public void setAddressConfig(Resource addressConfig) {
        this.addressConfig = addressConfig;
    }

    public void setTimeout(int timeout) {
        this.timeout = Integer.valueOf(timeout);
    }

    public void setMaxRedirections(int maxRedirections) {
        this.maxRedirections = Integer.valueOf(maxRedirections);
    }

    public void setAddressKeyPrefix(String addressKeyPrefix) {
        this.addressKeyPrefix = addressKeyPrefix;
    }

    public void setGenericObjectPoolConfig(GenericObjectPoolConfig genericObjectPoolConfig) {
        this.genericObjectPoolConfig = genericObjectPoolConfig;
    }
}

7、操作实现类,这里只提供了3个实现方法,其他的可以根据需求来

(ps:我这里是通过序列化方式来实现的key和value,所以不需要分List集合还是String字符串,统一对待,统一处理)

import org.springframework.stereotype.Component;
import redis.clients.jedis.JedisCluster;

import javax.annotation.Resource;

/**
 * Created by chengwenwen on 2016/11/4.
 */
@Component
public class RedisCache {

    @Resource
    private JedisCluster jedisCluster;

    /**
     * 添加缓存数据
     * @param key
     * @param obj
     * @param <T>
     * @return
     * @throws Exception
     */
    public <T> long putCache(String key, T obj) throws Exception {
        final byte[] bkey = key.getBytes();
        final byte[] bvalue = SerializerUtil.serializeObj(obj);
        return jedisCluster.setnx(bkey,bvalue);
    }


    /**
     * 添加缓存数据,设定缓存失效时间
     * @param key
     * @param obj
     * @param expireTime
     * @param <T>
     * @throws Exception
     */
    public <T> String putCacheWithExpireTime(String key, T obj, final int expireTime) throws Exception {
        final byte[] bkey = key.getBytes();
        final byte[] bvalue = SerializerUtil.serializeObj(obj);
        String result = jedisCluster.setex(bkey, expireTime,bvalue);
        return result;
    }

    /**
     * 根据key取缓存数据
     * @param key
     * @param <T>
     * @return
     * @throws Exception
     */
    public <T> T getCache(final String key) throws Exception {
        byte[] result = jedisCluster.get(key.getBytes());
        return (T) SerializerUtil.deserializeObj(result);
    }
}

8、测试代码

import com.topteam.redis.RedisCache;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 测试类
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath*:spring-test.xml")
public class test {
    @Resource
    private RedisCache redisCache;

    @Test
    public void test() throws Exception{
        List<String> list = new ArrayList<String>();
        list.add("测试list");
        list.add("测试list2");
        redisCache.putCache("testList","redis集群测试");

        Map<String,Object> map = new HashMap<String, Object>();
        map.put("test*","测试数据");
        map.put("测试数据","啥的");
        map.put("listTest",list);
        redisCache.putCache("testMap",map);

        redisCache.putCache("testString","redis集群测试");
        Map resultMap = new HashMap();
        resultMap.put("testList",redisCache.getCache("testList"));
        resultMap.put("testMap",redisCache.getCache("testMap"));
        resultMap.put("testString",redisCache.getCache("testString"));
        System.out.print(map);
    }
}

测试结果:

OK,一切正常。这里可以关闭一个主redis数据库服务,然后经过测试,还是可以获取数据。

  

  

posted @ 2016-11-21 18:18  沃弗码客  阅读(649)  评论(0编辑  收藏  举报
全网小程序源码分享