基于SpringBoot2.0默认使用Redis连接池的配置操作

网络编程 itxz 2个月前 (12-03) 53次浏览 0个评论

SpringBoot2.0默认采用Lettuce客户端来连接Redis服务端的

默认是不使用连接池的,只有配置 redis.lettuce.pool下的属性的时候才可以使用到redis连接池


redis:
 cluster:
  nodes: ${redis.host.cluster}
 password: ${redis.password}
 lettuce:
  shutdown-timeout: 100 # 关闭超时时间
  pool:
   max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
   max-idle: 8 # 连接池中的最大空闲连接
   max-wait: 30 # 连接池最大阻塞等待时间(使用负值表示没有限制)
   min-idle: 0 # 连接池中的最小空闲连接

没有这个配置时

基于SpringBoot2.0默认使用Redis连接池的配置操作

增加这个配置时
基于SpringBoot2.0默认使用Redis连接池的配置操作

同时,使用连接池,要依赖commons-pool2

<dependency>
   <groupId>org.apache.commons</groupId>
   <artifactId>commons-pool2</artifactId>
 </dependency>

如果没有引入,会报错
基于SpringBoot2.0默认使用Redis连接池的配置操作

同时如果你想使用jedis客户端,则需要配置

redis:
 cluster:
  nodes: ${redis.host.cluster}
 password: ${redis.password}
 jedis:
  pool:
   max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
   max-idle: 8 # 连接池中的最大空闲连接
   max-wait: 30 # 连接池最大阻塞等待时间(使用负值表示没有限制)
   min-idle: 0 # 连接池中的最小空闲连接

当然你也可以不配置,走默认的连接池配置,但是有一点要注意

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-data-redis</artifactId>
 <exclusions>
 <exclusion>
  <groupId>io.lettuce</groupId>
  <artifactId>lettuce-core</artifactId>
 </exclusion>
 </exclusions>
</dependency>
 
<dependency>
 <groupId>redis.clients</groupId>
 <artifactId>jedis</artifactId>
</dependency>

依赖包的引用里,要去掉lettuce,并且加上jedis的依赖包,否则都是走的lettuce客户端

同时jedis的客户端默认增加了pool的连接池依赖包,所以Jedis默认你配置与否都会有连接池,而lettuce则需要配置文件中配置一下

补充知识:解决springboot2 RedisTemplate使用lettuce连接池配置不生效的问题

springboot2 redis默认使用lettuce,使用连接池根据网上的内容,进行如下配置:

# 连接池最大连接数 使用负值表示没有限制
spring.redis.lettuce.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.lettuce.pool.max-wait=-1
# 连接池中的最大空闲连接 默认 8
spring.redis.lettuce.pool.max-idle=8
# 连接池中的最小空闲连接 默认 0
spring.redis.lettuce.pool.min-idle=0

但是启动后,多线程调用查询redis,通过redis-cli的info clients。

发现连接数并没有变多。

经过翻阅资料和源码发现,LettuceConnectionFactory类里面有个shareNativeConnection变量,默认为true。

说明共享本地连接,这样的话就不会创建多个连接了,连接池也就没用了。因此需要把这个值设为false。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import javax.annotation.Resource;
  
@Configuration
public class RedisConfig {
  @Resource
  private LettuceConnectionFactory lqlcfactory;
  @Bean
  public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) {
    RedisTemplate template = new RedisTemplate();
    template.setConnectionFactory(connectionFactory);
    return template;
  }
  
  @Bean
  public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
    StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
    lqlcfactory.setShareNativeConnection(false);
    stringRedisTemplate.setConnectionFactory(lqlcfactory);
    return stringRedisTemplate;
  }
}

这样lettuce连接池就设置成功了。

为什么改这里就可以了呢?从LettuceConnectionFactory的源码分析

/*
 * (non-Javadoc)
 * @see org.springframework.data.redis.connection.RedisConnectionFactory#getConnection()
 */
 public RedisConnection getConnection() {
  
 if (isClusterAware()) {
  return getClusterConnection();
 }
  
 LettuceConnection connection;
 connection = doCreateLettuceConnection(getSharedConnection(), connectionProvider, getTimeout(), getDatabase());
 connection.setConvertPipelineAndTxResults(convertPipelineAndTxResults);
 return connection;
 }
protected LettuceConnection doCreateLettuceConnection(
  @Nullable StatefulRedisConnection<byte[], byte[]> sharedConnection, LettuceConnectionProvider connectionProvider,
  long timeout, int database) {
  
 return new LettuceConnection(sharedConnection, connectionProvider, timeout, database);
 }

上面两个函数是获取connection连接,可以看到getSharedConnection()和shareNativeConnection配置有关了

@Nullable
 protected StatefulRedisConnection<byte[], byte[]> getSharedConnection() {
 return shareNativeConnection ? (StatefulRedisConnection) getOrCreateSharedConnection().getConnection() : null;
 }

如果是true,就是返回已经存在的连接,如果是false,返回null。那就只能创建新的连接了,如下

LettuceConnection(@Nullable StatefulConnection<byte[], byte[]> sharedConnection,
  LettuceConnectionProvider connectionProvider, long timeout, int defaultDbIndex) {
  
 Assert.notNull(connectionProvider, "LettuceConnectionProvider must not be null.");
  
 this.asyncSharedConn = sharedConnection;
 this.connectionProvider = connectionProvider;
 this.timeout = timeout;
 this.defaultDbIndex = defaultDbIndex;
 this.dbIndex = this.defaultDbIndex;
 }

IT学者 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:基于SpringBoot2.0默认使用Redis连接池的配置操作
喜欢 (2)

您必须 登录 才能发表评论!