如何隔离spring boot app redis和spring boot session全局redis

Posted

技术标签:

【中文标题】如何隔离spring boot app redis和spring boot session全局redis【英文标题】:How to isolate spring boot app redis and spring boot session global redis 【发布时间】:2018-06-06 12:33:52 【问题描述】:

据我所知,spring boot 和 spring session 为我们提供了一站式的自动配置,但是当我的应用程序使用 session redis 和 app cache redis 时,redis 服务器不一样; 怎么配置,非常感谢您的回复!

【问题讨论】:

【参考方案1】:

确实,默认情况下,spring-session 和 spring-cache 实际上都是由 spring-boot 配置的,带有一个名为 connectionFactoryRedisConnectionFactory bean。 有两种方法可以做到这一点。

    使spring-session 使用不同的connectionFactory bean 实例,并让spring-cache 使用默认的connectionFactory。下面是一个示例解决方案:

    @Configuration
    public class RedisHttpSessionConfig 
    
        @Bean
        StringRedisSerializer stringRedisSerializer() 
            return new StringRedisSerializer();
        
    
        @Bean
        RedisConnectionFactory redisHttpSessionConnectionFactory() 
            RedisConnectionFactory redisHttpSessionConnectionFactory = null;
            // ... add your codes here
            return redisHttpSessionConnectionFactory;
        
    
        @Bean
        public RedisTemplate<Object, Object> sessionRedisTemplate(
                RedisConnectionFactory redisHttpSessionConnectionFactory) 
            RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
            template.setKeySerializer(new StringRedisSerializer());
            template.setHashKeySerializer(new StringRedisSerializer());
            template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
            template.setDefaultSerializer(GenericJackson2JsonRedisSerializer());
            template.setConnectionFactory(redisHttpSessionConnectionFactory);
            return template;
        
    
    

    使spring-cache 使用不同的connectionFactory bean 实例,并让spring-session 使用默认的connectionFactory。下面是一个示例解决方案:

    @Configuration
    public class RedisCacheConfig 
    
        @Bean
        StringRedisSerializer stringRedisSerializer() 
            return new StringRedisSerializer();
        
    
        @Bean
        RedisConnectionFactory redisCacheConnectionFactory() 
             RedisConnectionFactory redisCacheConnectionFactory = null;
             // ... add your codes here
             return redisCacheConnectionFactory;
        
    
        @Bean
        RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisCacheConnectionFactory) 
            RedisTemplate<Object, Object> redisTemplate = new RedisTemplate();
            redisTemplate.setConnectionFactory(redisCacheConnectionFactory);
            redisTemplate.setKeySerializer(this.stringRedisSerializer());
            redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
            return redisTemplate;
        
    
        @Bean(name = "stringRedisTemplate")
        public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisCacheConnectionFactory) throws UnknownHostException 
            StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
            stringRedisTemplate.setConnectionFactory(redisCacheConnectionFactory);
            stringRedisTemplate.setKeySerializer(this.stringRedisSerializer());
            stringRedisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
            return stringRedisTemplate;
        
    
        @Bean
        CacheManager cacheManager(RedisTemplate redisTemplate) 
            RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
            cacheManager.setDefaultExpiration(600l);
            cacheManager.setUsePrefix(true);
            return cacheManager;
        
    
    

【讨论】:

【参考方案2】:

标记默认的 RedisConnectionFactory @Primary

    @Bean
    @Primary
    public RedisConnectionFactory redisConnectionFactory(RedisProperties properties) 
        return redisConnectionFactory(redisProperties);
    

并标记会话RedisConnectionFactory @SpringSessionRedisConnectionFactory

    @Bean
    @SpringSessionRedisConnectionFactory
    public RedisConnectionFactory springSessionRedisConnectionFactory() 
        return redisConnectionFactory(...);
    

redisConnectionFactory() 配置 RedisConnectionFactory。 例如:

private static RedisConnectionFactory redisConnectionFactory(RedisProperties redisProperties, boolean afterPropertiesSet) 
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        redisStandaloneConfiguration.setHostName(redisProperties.getHost());
        redisStandaloneConfiguration.setPassword(RedisPassword.of(redisProperties.getPassword()));
        redisStandaloneConfiguration.setDatabase(redisProperties.getDatabase());
        redisStandaloneConfiguration.setPort(redisProperties.getPort());

        GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
        genericObjectPoolConfig.setMaxIdle(redisProperties.getLettuce().getPool().getMaxIdle());
        genericObjectPoolConfig.setMinIdle(redisProperties.getLettuce().getPool().getMinIdle());
        genericObjectPoolConfig.setMaxTotal(redisProperties.getLettuce().getPool().getMaxActive());
        genericObjectPoolConfig.setMaxWaitMillis(redisProperties.getLettuce().getPool().getMaxWait().toMillis());
        genericObjectPoolConfig.setTestOnBorrow(true);
        genericObjectPoolConfig.setTestOnReturn(true);

        LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(redisStandaloneConfiguration,
                LettucePoolingClientConfiguration.builder().commandTimeout(redisProperties.getTimeout()).poolConfig(genericObjectPoolConfig).build());
        if (afterPropertiesSet) 
            lettuceConnectionFactory.afterPropertiesSet();
        
        return lettuceConnectionFactory;
    

【讨论】:

以上是关于如何隔离spring boot app redis和spring boot session全局redis的主要内容,如果未能解决你的问题,请参考以下文章

如何在模块化 Spring Boot 应用程序中定义隔离的 Web 上下文?

Spring Boot如何整合Redis

Spring Boot如何整合Redis

spring-boot redis:如何使用户的所有会话无效?

如何使用spring boot 2.x为redis集群设置密码

spring-boot配置Redis工具类