前言
JedisConnectionFacotory
从Spring Data Redis 2.0
开始已经不推荐直接显示设置连接的信息了,一方面为了使配置信息与建立连接工厂解耦,另一方面抽象出Standalone
,Sentinel
和RedisCluster
三种模式的环境配置类和一个统一的jedis客户端连接配置类(用于配置连接池和SSL连接),使得我们可以更加灵活方便根据实际业务场景需要来配置连接信息。
JavaConfig配置
不使用连接池
这里仅仅以Standalone
配置为例,其他情况类似。
1. 先创建RedisStandaloneConfiguration
2. 然后根据该配置实例来初始化jedis连接工厂。
@Bean
public JedisConnectionFactory jedisConnectionFactory() {
RedisStandaloneConfiguration redisStandaloneConfiguration =
new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setHostName("localhost");
redisStandaloneConfiguration.setDatabase(0);
redisStandaloneConfiguration.setPassword(RedisPassword.of("123456"));
redisStandaloneConfiguration.setPort(6380);
return new JedisConnectionFactory(redisStandaloneConfiguration);
}
@Bean
public StringRedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
return new StringRedisTemplate(redisConnectionFactory);
}
连接池配置
以上配置使用的是直接连接redis的方式,即每次连接都创建新的连接。当并发量剧增时,这会带来性能上开销,同时由于没有对连接数进行限制,则可能使服务器崩溃导致无法响应。所以我们一般都会建立连接池,事先初始化一组连接,供需要redis连接的线程取用。
首先我们定义连接池配置信息:
/**
* 连接池配置信息
* @return
*/
@Bean
public JedisPoolConfig jedisPoolConfig() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
//最大连接数
jedisPoolConfig.setMaxTotal(100);
//最小空闲连接数
jedisPoolConfig.setMinIdle(20);
//当池内没有可用的连接时,最大等待时间
jedisPoolConfig.setMaxWaitMillis(10000);
//------其他属性根据需要自行添加-------------
return jedisPoolConfig;
}
接下来配置连接工厂类,注意连接工厂类JedisConnectionFactory
对于Standalone模式竟然没有提供参数为(RedisStandaloneConfiguration,JedisPoolConfig)的构造函数。此处我非常不理解开发人员的想法。虽然JedisConnectionFactory
有一个内部JedisClientConfiguration
的实现类,但是访问权限仅限包内,我们无法使用,它的作用也仅仅作为默认的客户端连接配置。
若想配置standalone带有连接池配置的连接工厂类可谓是真的啰嗦,因为我们通常要自定义配置,但是JedisClientConfiguration
并没有提供带有参数为JedisPoolConfig的方法,它内部主张使用构造器来构建。令人不解的是,构造器竟然是采用仅包内访问的内部类的形式,也就是意味着你无法在外部访问这个内部类,所以只能先通过该接口的builder方法实例化出一个构造器,同时这个构造器会自带一个默认的连接池的配置,所以我们需要替换掉换成自己的配置类。这里又有一个坑,返回的对象的静态类型为JedisClientConfigurationBuilder
, 它确没有修改配置的接口方法,所以此处还得转型为JedisPoolingClientConfigurationBuilder
,然后调用其poolConfig即可替换为我们需要的配置。 最终我们就得到了如下非常不优雅的代码。
/**
* jedis连接工厂
* @param jedisPoolConfig
* @return
*/
@Bean
public RedisConnectionFactory redisConnectionFactory(JedisPoolConfig jedisPoolConfig) {
//单机版jedis
RedisStandaloneConfiguration redisStandaloneConfiguration =
new RedisStandaloneConfiguration();
//设置redis服务器的host或者ip地址
redisStandaloneConfiguration.setHostName("localhost");
//设置默认使用的数据库
redisStandaloneConfiguration.setDatabase(0);
//设置密码
redisStandaloneConfiguration.setPassword(RedisPassword.of("123456"));
//设置redis的服务的端口号
redisStandaloneConfiguration.setPort(6380);
//获得默认的连接池构造器(怎么设计的,为什么不抽象出单独类,供用户使用呢)
JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jpcb =
(JedisClientConfiguration.JedisPoolingClientConfigurationBuilder)JedisClientConfiguration.builder();
//指定jedisPoolConifig来修改默认的连接池构造器(真麻烦,滥用设计模式!)
jpcb.poolConfig(jedisPoolConfig);
//通过构造器来构造jedis客户端配置
JedisClientConfiguration jedisClientConfiguration = jpcb.build();
//单机配置 + 客户端配置 = jedis连接工厂
return new JedisConnectionFactory(redisStandaloneConfiguration, jedisClientConfiguration);
}
总结
很显然这里利用策略模式来使得连接工厂可以根据不同的方案来创建相应的连接,创建连接过程与配置连接信息完全解耦,方便以后拓展jedis更多的配置信息,赞!
但是JedisClientConfiguration
的构造器模式个人感觉在此处设计欠佳,你们的观点呢?
另外,Spring Data Redis 2.0
已经将jedis移除,如果仍然希望使用jedis,需要额外引入jedis的依赖项。standalone带有连接池的jedisConnnectionFactory配置如此繁琐,这也反映了开发者正在废弃jedis。
SpringBoot2.0整合redis
在springboot中如果想配置成带有连接池的单机redis,简直太简单了,这来源于springboot的自动化配置。
首先,如果你采用maven来构建项目,那么在pom文件中添加如下依赖:
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.0.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
我们只需在application.properties文件中,添加如下代码即可享受redis的好处:
# redis单机应用环境配置
spring.redis.host=127.0.0.1
spring.redis.database=0
spring.redis.port=6380
spring.redis.password=123456
# redis连接池配置
spring.redis.jedis.pool.max-active=200
spring.redis.jedis.pool.min-idle=20
spring.redis.jedis.pool.max-wait=3000ms