zoukankan      html  css  js  c++  java
  • 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数据库服务,然后经过测试,还是可以获取数据。

      

      

  • 相关阅读:
    Windows系统批处理命令实现计划关机
    Git如何将本地test分支设置跟踪origin/test分支
    JavaScript动态实现div窗口弹出&消失功能
    深入理解 Array.prototype.map()
    JS中集合对象(Array、Map、Set)及类数组对象的使用与对比
    Vue的移动端多图上传插件vue-easy-uploader
    如何开发一个npm包并发布
    emlog编辑器探寻之旅
    linux下安装nginx
    原生JavaScript中动画与特效的实现原理
  • 原文地址:https://www.cnblogs.com/hz-cww/p/6086201.html
Copyright © 2011-2022 走看看