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);
  • 相关阅读:
    leetcode之String to Integer (atoi)
    初次思考
    leetcode之Reverse Words in a String
    Leetcode之Database篇
    在项目中添加类
    创建项目
    配置Eclipse

    递归
    多态
  • 原文地址:https://www.cnblogs.com/007sx/p/10120103.html
Copyright © 2011-2022 走看看