兰陵笑个人博客

愿居于一城,与卿所见美好......

推荐文章

Spring Boot 多数据源 Redis 配置lettuce客户端

    概述

    本文基于spring boot 2.0.7,讲解如何配置多数据源redis,采用lettuce做为redis客户端,并附上示例代码。

    

    redis配置

    配置文件

    skyarthur:
      redis1:
        host: 127.0.0.1
        port: 6378
        lettuce:
          pool:
            min-idle: 5
            max-idle: 10
            max-active: 8
            max-wait: 1ms
          shutdown-timeout: 100ms
      redis2:
        host: 127.0.0.1
        port: 6379
        lettuce:
          pool:
            min-idle: 5
            max-idle: 10
            max-active: 8
            max-wait: 1ms
          shutdown-timeout: 100ms

    共配置2个redis数据源,并采用 lettuce pool 做为redis客户端

    配置类

    package com.skyarthur.springboot.config;
    import io.lettuce.core.resource.ClientResources;
    import io.lettuce.core.resource.DefaultClientResources;
    import lombok.Getter;
    import lombok.Setter;
    import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
    import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Primary;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.connection.RedisPassword;
    import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
    import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
    import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
    import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
    import org.springframework.data.redis.core.StringRedisTemplate;
    /**
     * Created by skyarthur on 2019-12-21
     */
    @Configuration
    @ConfigurationProperties(prefix = "skyarthur")
    @Getter
    @Setter
    public class RedisConfig {
        private RedisProperties redis1;
        private RedisProperties redis2;
        @Bean(destroyMethod = "shutdown")
        @ConditionalOnMissingBean(ClientResources.class)
        public DefaultClientResources lettuceClientResources() {
            return DefaultClientResources.create();
        }
        @Bean(name = "stringRedisTemplate1")
        @Primary
        public StringRedisTemplate stringRedisTemplate1(
                @Qualifier("Redis1LettuceConnectionFactory") RedisConnectionFactory redisConnectionFactory) {
            StringRedisTemplate template = new StringRedisTemplate();
            template.setConnectionFactory(redisConnectionFactory);
            return template;
        }
        @Bean(name = "Redis1LettuceConnectionFactory")
        @Primary
        public LettuceConnectionFactory Redis1LettuceConnectionFactory(ClientResources clientResources) {
            RedisStandaloneConfiguration redis1StandaloneConfiguration = getStandaloneConfig(redis1);
            LettuceClientConfiguration clientConfig = getLettuceClientConfiguration(clientResources, redis1);
            return new LettuceConnectionFactory(redis1StandaloneConfiguration, clientConfig);
        }
        @Bean(name = "stringRedisTemplate2")
        public StringRedisTemplate stringRedisTemplate2(
                @Qualifier("Redis2LettuceConnectionFactory") RedisConnectionFactory redisConnectionFactory) {
            StringRedisTemplate template = new StringRedisTemplate();
            template.setConnectionFactory(redisConnectionFactory);
            return template;
        }
        @Bean(name = "Redis2LettuceConnectionFactory")
        public LettuceConnectionFactory Redis2LettuceConnectionFactory(ClientResources clientResources) {
            RedisStandaloneConfiguration redis1StandaloneConfiguration = getStandaloneConfig(redis2);
            LettuceClientConfiguration clientConfig = getLettuceClientConfiguration(clientResources, redis2);
            return new LettuceConnectionFactory(redis1StandaloneConfiguration, clientConfig);
        }
        /**
         * redis standalone config
         *
         * @param redisProperties redis 配置参数
         * @return RedisStandaloneConfiguration
         */
        private RedisStandaloneConfiguration getStandaloneConfig(RedisProperties redisProperties) {
            RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
            config.setHostName(redisProperties.getHost());
            config.setPort(redisProperties.getPort());
            config.setPassword(RedisPassword.of(redisProperties.getPassword()));
            config.setDatabase(redisProperties.getDatabase());
            return config;
        }
        /**
         * 构建 LettuceClientConfiguration
         *
         * @param clientResources clientResources
         * @param redisProperties redisProperties
         * @return LettuceClientConfiguration
         */
        private LettuceClientConfiguration getLettuceClientConfiguration(ClientResources clientResources,
                                                                         RedisProperties redisProperties) {
            LettuceClientConfiguration.LettuceClientConfigurationBuilder builder =
                    createBuilder(redisProperties.getLettuce().getPool());
            if (redisProperties.isSsl()) {
                builder.useSsl();
            }
            if (redisProperties.getTimeout() != null) {
                builder.commandTimeout(redisProperties.getTimeout());
            }
            if (redisProperties.getLettuce() != null) {
                RedisProperties.Lettuce lettuce = redisProperties.getLettuce();
                if (lettuce.getShutdownTimeout() != null
                        && !lettuce.getShutdownTimeout().isZero()) {
                    builder.shutdownTimeout(
                            redisProperties.getLettuce().getShutdownTimeout());
                }
            }
            builder.clientResources(clientResources);
            return builder.build();
        }
        /**
         * 创建 LettuceClientConfigurationBuilder
         *
         * @param pool 连接池配置
         * @return LettuceClientConfigurationBuilder
         */
        private LettuceClientConfiguration.LettuceClientConfigurationBuilder createBuilder(RedisProperties.Pool pool) {
            if (pool == null) {
                return LettuceClientConfiguration.builder();
            }
            return LettucePoolingClientConfiguration.builder()
                    .poolConfig(getPoolConfig(pool));
        }
        /**
         * pool config
         *
         * @param properties redis 参数配置
         * @return GenericObjectPoolConfig
         */
        private GenericObjectPoolConfig getPoolConfig(RedisProperties.Pool properties) {
            GenericObjectPoolConfig config = new GenericObjectPoolConfig();
            config.setMaxTotal(properties.getMaxActive());
            config.setMaxIdle(properties.getMaxIdle());
            config.setMinIdle(properties.getMinIdle());
            if (properties.getMaxWait() != null) {
                config.setMaxWaitMillis(properties.getMaxWait().toMillis());
            }
            return config;
        }
    } //+V:BGM7756,免费领取资料

    以上配置主要参考 spring 官方配置 RedisAutoConfiguration, LettuceConnectionConfiguration。简单来说:RedisAutoConfiguration注册了2个bean,RedisTemplate和StringRedisTemplate,这两个bean又依赖RedisConnectionFactory的注入,在RedisAutoConfiguration可以看到,RedisConnectionFactory有两个实现,LettuceConnectionFactory和JedisConnectionFactory,具体可以直接参考官方配置LettuceConnectionConfiguration

    单测

    package com.skyarthur.springboot.config;
    import com.skyarthur.springboot.ApplicationTests;
    import com.skyarthur.springboot.common.enums.RedisType;
    import org.junit.Assert;
    import org.junit.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
    import org.springframework.data.redis.core.StringRedisTemplate;
    /**
     * Created by skyarthur on 2019-12-21
     */
    public class RedisConfigTest extends ApplicationTests {
        @Autowired
        @Qualifier("stringRedisTemplate1")
        private StringRedisTemplate stringRedisTemplate1;
        @Autowired
        @Qualifier("stringRedisTemplate2")
        private StringRedisTemplate stringRedisTemplate2;
        @Test
        public void test() {
            LettuceConnectionFactory factory = (LettuceConnectionFactory) stringRedisTemplate1.getConnectionFactory();
            Assert.assertNotNull(factory);
            Assert.assertEquals(6378, factory.getPort());
            Assert.assertEquals("127.0.0.1", factory.getHostName());
            factory = (LettuceConnectionFactory) stringRedisTemplate2.getConnectionFactory();
            Assert.assertNotNull(factory);
            Assert.assertEquals(6379, factory.getPort());
            Assert.assertEquals("127.0.0.1", factory.getHostName());
            stringRedisTemplate1.opsForValue().set(RedisType.PERSON_INFO.getRealKey("test"), "6378");
            stringRedisTemplate2.opsForValue().set("test", "6379");
            Assert.assertEquals("6378", stringRedisTemplate1.opsForValue().get(RedisType.PERSON_INFO.getRealKey("test")));
            Assert.assertEquals("6379", stringRedisTemplate2.opsForValue().get("test"));
        }
    } //+V:BGM7756,免费领取资料

    阅读全文>>

作者:兰陵笑分类:【javaEE浏览(230评论(0

2020-12-17 18:45:50