zoukankan      html  css  js  c++  java
  • springboot2.x版本整合redis(单机/集群)(使用lettuce)

    springboot1.x系列中,其中使用的是jedis,但是到了springboot2.x其中使用的是Lettuce。 此处springboot2.x,所以使用的是Lettuce
    关于jedislettuce的区别:

    • Lettuce 和 Jedis 的定位都是Redis的client,所以他们当然可以直接连接redis server。
    • Jedis在实现上是直接连接的redis server,如果在多线程环境下是非线程安全的,这个时候只有使用连接池,为每个Jedis实例增加物理连接
    • Lettuce的连接是基于Netty的,连接实例(StatefulRedisConnection)可以在多个线程间并发访问,应为StatefulRedisConnection是线程安全的,所以一个连接实例(StatefulRedisConnection)就可以满足多线程环境下的并发访问,当然这个也是可伸缩的设计,一个连接实例不够的情况也可以按需增加连接实例。

    新建一个springboot工程,添加如下pom依赖。

    <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
    
            <!-- redis依赖commons-pool 这个依赖一定要添加 -->
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-pool2</artifactId>
            </dependency>

    然后在application.yml配置一下redis服务器的地址

    server:
      port: 1015
    spring:
      redis:
        cache:
          nodes: -192.168.159.129:7001
                 -192.168.159.129:7002
                 -192.168.159.129:7003
                 -192.168.159.129:7004
                 -192.168.159.129:7005
                 -192.168.159.129:7006
          host: localhost:6379
          password:
          maxIdle:
          minIdle:
          maxTotal:
          maxWaitMillis: 5000

    其中nodes为集群redis的参数 host为单机redis的参数

    redis配置类:

    package webapp.conf;
    
    import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.connection.RedisClusterConfiguration;
    import org.springframework.data.redis.connection.RedisNode;
    import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
    import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
    import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.serializer.RedisSerializer;
    import org.springframework.data.redis.serializer.SerializationException;
    
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.util.HashSet;
    import java.util.Set;
    
    @Configuration
    public class RedisConfiguration {
        @Value("${spring.redis.cache.nodes:}")
        private String nodes;
        @Value("${spring.redis.cache.host:}")
        private String host;
        @Value("${spring.redis.cache.password:}")
        private String password;
        @Value("${spring.redis.cache.maxIdle:}")
        private Integer maxIdle;
        @Value("${spring.redis.cache.minIdle:}")
        private Integer minIdle;
        @Value("${spring.redis.cache.maxTotal:}")
        private Integer maxTotal;
        @Value("${spring.redis.cache.maxWaitMillis:}")
        private Long maxWaitMillis;
    
        @Bean
        LettuceConnectionFactory lettuceConnectionFactory() {
            // 连接池配置
            GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
            poolConfig.setMaxIdle(maxIdle == null ? 8 : maxIdle);
            poolConfig.setMinIdle(minIdle == null ? 1 : minIdle);
            poolConfig.setMaxTotal(maxTotal == null ? 8 : maxTotal);
            poolConfig.setMaxWaitMillis(maxWaitMillis == null ? 5000L : maxWaitMillis);
            LettucePoolingClientConfiguration lettucePoolingClientConfiguration = LettucePoolingClientConfiguration.builder()
                    .poolConfig(poolConfig)
                    .build();
            // 单机redis
            RedisStandaloneConfiguration redisConfig = new RedisStandaloneConfiguration();
            redisConfig.setHostName(host==null||"".equals(host)?"localhost":host.split(":")[0]);
            redisConfig.setPort(Integer.valueOf(host==null||"".equals(host)?"6379":host.split(":")[1]));
            if (password != null && !"".equals(password)) {
                redisConfig.setPassword(password);
            }
    
            // 哨兵redis
            // RedisSentinelConfiguration redisConfig = new RedisSentinelConfiguration();
    
            // 集群redis
            /*RedisClusterConfiguration redisConfig = new RedisClusterConfiguration();
            Set<RedisNode> nodeses = new HashSet<>();
            String[] hostses = nodes.split("-");
            for (String h : hostses) {
                h = h.replaceAll("\s", "").replaceAll("
    ", "");
                if (!"".equals(h)) {
                    String host = h.split(":")[0];
                    int port = Integer.valueOf(h.split(":")[1]);
                    nodeses.add(new RedisNode(host, port));
                }
            }
            redisConfig.setClusterNodes(nodeses);
            // 跨集群执行命令时要遵循的最大重定向数量
            redisConfig.setMaxRedirects(3);
            redisConfig.setPassword(password);*/
    
            return new LettuceConnectionFactory(redisConfig, lettucePoolingClientConfiguration);
        }
    
        @Bean
        public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
            RedisTemplate<String, Object> template = new RedisTemplate<>();
            template.setConnectionFactory(lettuceConnectionFactory);
            //序列化类
            MyRedisSerializer myRedisSerializer = new MyRedisSerializer();
            //key序列化方式
            template.setKeySerializer(myRedisSerializer);
            //value序列化
            template.setValueSerializer(myRedisSerializer);
            //value hashmap序列化
            template.setHashValueSerializer(myRedisSerializer);
            return template;
        }
    
        static class MyRedisSerializer implements RedisSerializer<Object> {
    
            @Override
            public byte[] serialize(Object o) throws SerializationException {
                return serializeObj(o);
            }
    
            @Override
            public Object deserialize(byte[] bytes) throws SerializationException {
                return deserializeObj(bytes);
            }
    
            /**
             * 序列化
             * @param object
             * @return
             */
            private 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
             */
            private 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);
                }
            }
        }
    }    

    以上已经完成整合教程,测试案例:

    注入:

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    添加:

    redisTemplate.opsForValue().set(key, value);

    添加,设置过期时间:

    redisTemplate.opsForValue().set(key, obj, expireTime, TimeUnit.SECONDS);

    获取:

    Object o = redisTemplate.opsForValue().get(key);

    删除:

    redisTemplate.delete(key);
  • 相关阅读:
    Java实现 LeetCode 30 串联所有单词的子串
    Java实现 LeetCode 29 两数相除
    Java实现 LeetCode 29 两数相除
    Java实现 LeetCode 29 两数相除
    Java实现 LeetCode 28 实现strStr()
    Java实现 LeetCode 28 实现strStr()
    Java实现 LeetCode 28 实现strStr()
    Java实现 LeetCode 27 移除元素
    Java实现 LeetCode 27 移除元素
    字符编码终极笔记:ASCII、Unicode、UTF-8、UTF-16、UCS、BOM、Endian
  • 原文地址:https://www.cnblogs.com/007sx/p/10120103.html
Copyright © 2011-2022 走看看