JedisCluster操作Redis集群和sessian的存储与读取

去年的项目用的就是Redis集群做外围数据的接收存储,再定时发送给主系统,最近打算将一部分
对象的缓存也放到Redis上,就趁着这个时间点,将代码梳理下,好于将来再用。

此项目用的dubbo+maven架构的,项目结构图

这里写图片描述

配置文件

redis_faction.xml,项目主要配置文件主要存于service项目中

<?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">
            <!-- redis 配置线程池  -->
    <bean name="genericObjectPoolConfig" class="org.apache.commons.pool2.impl.GenericObjectPoolConfig">
        <property name="maxWaitMillis" value="-1" />
        <property name="maxTotal" value="1000" />
        <property name="minIdle" value="8" />
        <property name="maxIdle" value="100" />
    </bean>
        <!-- 初始化JedisClusterFactory -->
    <bean id="jedisCluster" class="com.ljp.Faction.JedisClusterFactory">
        <property name="addressKeyPrefix" value="address" />
        <property name="timeout" value="300000" />
        <property name="maxRedirections" value="6" />
        <property name="genericObjectPoolConfig" ref="genericObjectPoolConfig" />
    </bean>
</beans>

JedisClusterFactory.java

package com.ljp.Faction;

import java.io.InputStream;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Pattern;

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;

public class JedisClusterFactory implements FactoryBean<JedisCluster>, InitializingBean {
    private String addressKeyPrefix;
    private JedisCluster jedisCluster;
    private String timeout;
    private String maxRedirections;
    private GenericObjectPoolConfig genericObjectPoolConfig;

    // 非空初始化
    public GenericObjectPoolConfig getGenericObjectPoolConfig() {
        GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
        genericObjectPoolConfig.setMaxWaitMillis(1000);
        genericObjectPoolConfig.setMaxTotal(20000);
        genericObjectPoolConfig.setMaxIdle(20);
        genericObjectPoolConfig.setTestOnBorrow(true);
        return genericObjectPoolConfig;
    }

    private Pattern p = Pattern.compile("^.+[:]\\d{1,5}\\s*$");

    public JedisCluster getObject() throws Exception {
        afterPropertiesSet();
        return 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 prop = new Properties();
            // 读取属性文件 PS:我的项目有问题,Spring 注入不进去 不知道咋回事,所以我就用了这种方式 给redis 做了初始化
            InputStream in = getClass().getClassLoader().getResourceAsStream("connect-redis.properties");
            prop.load(in);
            Set<HostAndPort> haps = new HashSet<HostAndPort>();
            if (addressKeyPrefix == null) {
                addressKeyPrefix = "address";
            }
            for (Object key : prop.keySet()) {

                if (!((String) key).startsWith(addressKeyPrefix)) {
                    continue;
                }

                String val = (String) prop.get(key);

                boolean isIpPort = 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 ex) {
            throw ex;
        } catch (Exception ex) {
            throw new Exception("解析 redis 配置文件失败", ex);
        }
    }

    public void afterPropertiesSet() throws Exception {
        Set<HostAndPort> haps = this.parseHostAndPort();
        if (genericObjectPoolConfig == null) {
            genericObjectPoolConfig = getGenericObjectPoolConfig();
        }
        jedisCluster = new JedisCluster(haps, genericObjectPoolConfig);

    }

    public void setTimeout(String timeout) {
        this.timeout = timeout;
    }

    public void setMaxRedirections(String maxRedirections) {
        this.maxRedirections = maxRedirections;
    }

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

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

}

connect-redis.properties配置文件

address1=20.4.16.10:6379
address2=20.4.16.10:7002
address3=20.4.16.10:7003
address4=20.4.16.10:7004
address5=20.4.16.10:7005
address6=20.4.16.10:7006

然后是对象序列化和反序列化的SerializerUtil.java

package com.ljp.Faction;

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

import Entity.Man;

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);
        }
    }

    public static void main(String[] args) {
        Man m = new Man();
        m.setAge(121223);
        m.setId(35135334L);
        m.setName("zhangsan");
        byte[] serializeObj = SerializerUtil.serializeObj(m);

        Man deserializeObj = (Man) deserializeObj(serializeObj);
        System.out.println(deserializeObj.getAge());
        System.out.println(deserializeObj.getName());
        System.out.println(deserializeObj.getId());
    }

    /**
     * 反序列化
     * 
     * @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);
        }
    }
}
这个是我测试序列化的结果

这里写图片描述

然后就是dao层的持久化了,测试代码,此处省略了dao层,持久化东西放到了sevice中

RedisImp.java

package com.ljp;

import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
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;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.dubbo.common.utils.StringUtils;
import com.ljp.Faction.SerializerUtil;

import Entity.Man;
import redis.clients.jedis.JedisCluster;

@Service("redisService")
@Transactional
public class RedisImp implements RedisInterface {

    @Autowired
    private JedisCluster jedisCluster;

    public String set(String... content) {
        for (String string : content) {
            System.out.println(string);
        }
        String set = jedisCluster.set(content[0], content[1]);
        System.out.println("Redis setString value----  " + set);
        return "set";
    }

    // 序列化存储对象定时时间
    public String set(String id, Man m) {
        byte[] serializeObj = SerializerUtil.serializeObj(id);
        byte[] serialize = SerializerUtil.serializeObj(m);
        jedisCluster.setex(serializeObj, 60, serializeObj);
        String set = "  ";
        System.out.println("Redis setString value----  " + set);
        return "set";
    }

    public String get(String... content) {
        System.out.println(content[0]);
        String string = jedisCluster.get(content[0]);
        System.out.println("redis  getString value----" + string);
        if (StringUtils.isEmpty("string")) {
            return null;
        }
        return string;
    }

    public Long lpush(String... content) {
        Long lpush = jedisCluster.lpush(content[0], content[1]);
        return lpush;
    }

    public List<String> lrange(String... content) {
        List<String> lrange = jedisCluster.lrange(content[0], Long.valueOf(content[1]), Long.valueOf(content[1]));
        return lrange;
    }

    public Long sadd(String... content) {
        Long sadd = jedisCluster.sadd(content[0], content[1]);
        return sadd;
    }

    public Set<String> smembers(String... content) {
        Set<String> smembers = jedisCluster.smembers(content[0]);
        // TODO Auto-generated method stub
        return smembers;
    }

    public Long zadd(String... content) {
        // TODO Auto-generated method stub
        return null;
    }

    public Set<String> zrange(String... content) {
        // TODO Auto-generated method stub
        return null;
    }

    public long delByKey(String key) {
        // TODO Auto-generated method stub
        return 0;
    }

    public long delByValue(String... content) {
        // TODO Auto-generated method stub
        return 0;
    }

}

这个操作存储我也看了不少博客才总结的,这是我自己整理出来的可以用的,直接粘贴复制
就行,代码中实现了对象Man的存储。这个和sessian是一样的,想必都会自己转换,如果异常,如果有什么地方不懂或者需要优化的可以联系我

猜你喜欢

转载自blog.csdn.net/xuxie13/article/details/79278232
今日推荐