Redis 基于 Spring Boot 的配置方法

文章参照:

http://gitbook.cn/gitchat/column/5a4ce2005e04d7622ba2b256/topic/5a4d9090b16db6596f5a3d72

以 Spring Boot 为例分别介绍一下这四种配置方法:

(1)基本使用;
(2)连接池的使用;
(3)高可用连接(master/salve);
(4)客户端分片。

添加 Spring Data Redis 依赖

<!--如果是 Spring Boot 项目直接添加 spring-boot-starter-data-redis 即可。-->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

分析一下源码

一旦当我们使用 Spring Boot,其实任何一个 starter 都会引入 spring-boot-autoconfigure 的 jar 包,然后 autoconfigure 就会做很多事情。

SpringBootStarterRedis 源码分析

我们用 Spring Boot 都知道 starter 的原理(spring-boot-autoconfigure.jar 包里面的 spring.factories 定义了 Spring Boot 默认加载的 AutoConfiguration),因此,打开 spring.factories 文件可以找到 Spring 自动加载了。

org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,

这两个 Configuration 类,我们先打开 RedisAutoConfiguration 的源码 ,来一起看一下里面的关键代码片段。

(1)代码片段一:自动加载 JedisConnectionFactory。

@Bean
@ConditionalOnMissingBean(RedisConnectionFactory.class)
public JedisConnectionFactory redisConnectionFactory()
        throws UnknownHostException {
    return applyProperties(createJedisConnectionFactory());
}

通过这一段代码可以看到,JedisConnectionFactory 可以自己配置也可以直接用 Spring Boot 给我们提供的默认配置。

(2)代码片段二:查看 createJedisConnectionFactory() 的具体方法。

private JedisConnectionFactory createJedisConnectionFactory() {
    //这里会取我们配置文件里面的配置,如果没有配置,new 一个默认连接池
    JedisPoolConfig poolConfig = this.properties.getPool() != null
            ? jedisPoolConfig() : new JedisPoolConfig();

    //如果配置了Sentinel就取哨兵的配置直接返回
    if (getSentinelConfig() != null) {
        return new JedisConnectionFactory(getSentinelConfig(), poolConfig);
    }
    //如果没有配置中Sentinel,而配置了Cluster切片的配置方法,它就取Cluster的配置方法
    if (getClusterConfiguration() != null) {
        return new JedisConnectionFactory(getClusterConfiguration(), poolConfig);
    }
    //默认取连接pool的配置方法
    return new JedisConnectionFactory(poolConfig);
}
.......
//取配置文件里面的Pool的配置
private JedisPoolConfig jedisPoolConfig() {
    JedisPoolConfig config = new JedisPoolConfig();
    RedisProperties.Pool props = this.properties.getPool();
    config.setMaxTotal(props.getMaxActive());
    config.setMaxIdle(props.getMaxIdle());
    config.setMinIdle(props.getMinIdle());
    config.setMaxWaitMillis(props.getMaxWait());
    return config;
}
.......
//JedisPoolConfig的类默认构造函数
public class JedisPoolConfig extends GenericObjectPoolConfig {
    public JedisPoolConfig() {
        this.setTestWhileIdle(true);
        this.setMinEvictableIdleTimeMillis(60000L);
        this.setTimeBetweenEvictionRunsMillis(30000L);
        this.setNumTestsPerEvictionRun(-1);
    }
}

通过这段代码可以看出来,前面讲到的四种 Jedis 的配置方式,这里默认只支持了三种。 Spring 将 Pool 作为默认的配置方法。 可以看出:

其一,三种配置中 Pool(连接池)、Sentinel(哨兵,master/slave)和 Cluster(切片)只能选择一种来配置。
其二,只需要配置我们的配置文件就可以了,剩下的就交给 Spring 的 JedisConnectionFactory。

(3)代码片段三:查看 RedisAutoConfiguration 的关键源码。

@Configuration
@ConditionalOnClass({ JedisConnection.class, RedisOperations.class, Jedis.class })
@EnableConfigurationProperties(RedisProperties.class)
public class RedisAutoConfiguration {
......
}
@ConfigurationProperties(prefix = "spring.redis")
public class RedisProperties {
    /**
     * Database index used by the connection factory.
     */
    private int database = 0;
    /**
     * Redis url, which will overrule host, port and password if set.
     */
    private String url;
    /**
     * Redis server host.
     */
    private String host = "localhost";
    /**
     * Login password of the redis server.
     */
    private String password;
    /**
     * Redis server port.
     */
    private int port = 6379;
    /**
     * Enable SSL.
     */
    private boolean ssl;
    /**
     * Connection timeout in milliseconds.
     */
    private int timeout;

    private Pool pool;

    private Sentinel sentinel;

    private Cluster cluster;
    ......
}

这里省略了一些中间的代码,有兴趣的读者可以看一下源码,到这一步,其实已经发现了配置文件应该怎么配置了(PS:字段名字 +spring.redis 前缀就是 application.yml 里面的 key了)。如果使用 Intellij IDEA,当在 application.properties 输入 spring.redis 开头的 key 值的时候会给我们提示这类里面的属性值。

(4)代码片段四: RedisConfiguration 关键源码。

/**
     * Standard Redis configuration.
     */
    @Configuration
    protected static class RedisConfiguration {

        @Bean
        @ConditionalOnMissingBean(name = "redisTemplate")
        public RedisTemplate<Object, Object> redisTemplate(
                RedisConnectionFactory redisConnectionFactory)
                        throws UnknownHostException {
            RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
            template.setConnectionFactory(redisConnectionFactory);
            return template;
        }

        @Bean
        @ConditionalOnMissingBean(StringRedisTemplate.class)
        public StringRedisTemplate stringRedisTemplate(
                RedisConnectionFactory redisConnectionFactory)
                        throws UnknownHostException {
            StringRedisTemplate template = new StringRedisTemplate();
            template.setConnectionFactory(redisConnectionFactory);
            return template;
        }

    }

由以上代码可知,我们可以使用类 RedisTemplate 或者 StringRedisTemplate 来直接操作 Redis 的 client 的相关 API.

配置方法

基本使用配置方法 & 连接池的配置方法,只需要在我们的 application.properties 里面增加如下配置即可。

spring.redis.host=127.0.0.1 #redis服务器地址
spring.redis.port=6379 #端口
spring.redis.timeout=6000 #连接超时时间 毫秒
spring.redis.pool.max-active=8 # 连接池的配置,最大连接激活数
spring.redis.pool.max-idle=8 # 连接池配置,最大空闲数
spring.redis.pool.max-wait=-1 #  连接池配置,最大等待时间
spring.redis.pool.min-idle=0 # 连接池配置,最小空闲活动连接数

调用的地方就可以直接引用 redisTemplate 进行使用了。这时候启动的 pool 的很多设置,如果不配置 pool 的一些相关参数,我们看源码的话,也会发现启动 JedisPoolConfig 里面的默认配置(源码分析里面的代码片段二里面的内容)。

实例 DEMO1

//例如某个Service里面只需要引用RedisTemplate类即可:
@Autowired
private static RedisTemplate redisTemplate;
//某个service方法中,直接调用redisTemplate操作redis的set集合,储存keyvalue
public Object cacheAround(String key,String value) throws Throwable {
    ....
    //直接调用redisTemplate操作redis的set集合,储存keyvalue
    redisTemplate.opsForSet().add(key,value);
    //这里不需要,关心redisTemplate里面配置的是连接池,还是哨兵,还是cluster。
    .....
}

sentinel 哨兵的高可用配置方法

我们可以看 RedisProperties 的 Sentinel 类得出如下配置方式:只需要在
application.properties 里面配置如下内容即可。

spring.redis.sentinel.master= redis_master_name #master 名字
spring.redis.sentinel.nodes= 127.0.0.1:63791,127.0.0.1:63792  #我们配置多个哨兵,用","分割即可

使用的地方保持不变,这就体现了 Spring 的大牛们超强的封装思想,当改变 Redis 的 Server 使用方式的时候,让 redisTemplate 使用的地方不受任何影响,这里体现了 Java 的封装思想(因为我们只需要改变配置文件即可,调用的地方不需要发生任何改变,如上面的实例 DEMO1)。

Cluster 分布式切片的配置方法

RedisProperties 的 Cluster 类得出如下配置方式:只需要在 application.properties 里面配置如下内容即可。

spring.redis.cluster.max-redirects=3 # Maximum number of redirects to follow when executing commands across the cluster.
spring.redis.cluster.nodes= 127.0.0.1:6379,127.0.0.1:6376,127.0.0.1:6378# Comma-separated list of "host:port" pairs to bootstrap from.

总结Spring Boot 的配置方法:

引入 spring-boot-starter-data-redis.jar 包的依赖。
修改 application.properties 文件的三种配置方法即可。
直接调用 RedisTemplate 进行 Redis 的相关操作。

猜你喜欢

转载自blog.csdn.net/u013412772/article/details/80315120