如何在不增加连接数超过 maxtotal 的情况下高效使用 JedisConfig 池?

dev*_*333 1 connection-pooling redis jedis spring-boot

Jedis 池没有按预期工作。我提到了活动连接数 10,但它甚至允许超过 10 个连接。

我已经重写了 RedisConnectionFactory 中的 getConnection() 方法。为了获取连接,该方法已被调用近 30 次。

我已经配置了 jedis 配置池,如下所述。有人可以帮我解释一下为什么它创建的连接数超过了最大总数吗?有人可以帮我关闭 jedisconnection 池吗?

@Configuration
public class RedisConfiguration {
        @Bean
        public RedisTenantDataFactory redisTenantDataFactory(){
        JedisPoolConfig poolConfig = new JedisPoolConfig();
                        poolConfig.setMaxIdle(1);
                        poolConfig.setMaxTotal(10);
                        poolConfig.setBlockWhenExhausted(true);
                        poolConfig.setMaxWaitMillis(10);
                        
                        JedisConnectionFactory jedisConnectionFactory = new 
                        JedisConnectionFactory(poolConfig);
                        jedisConnectionFactory.setHostName(redisHost);
                        jedisConnectionFactory.setUsePool(true);
                        jedisConnectionFactory.setPort(Integer.valueOf(redisPort));
    }
    
        #####
           @Bean
            public RedisTemplate<String, Object> redisTemplate(@Autowired RedisConnectionFactory redisConnectionFactory) {
                RedisTemplate<String, Object> template = new RedisTemplate<>();
                template.setConnectionFactory(redisConnectionFactory);
                template.afterPropertiesSet();
                return template;
            }
}
Run Code Online (Sandbox Code Playgroud)

我已经重写了 RedisConnectionFactory 中的 getConnection() 方法。为了获取连接,该方法已被调用近 30 次。

Tug*_*all 5

这可能是对 ConnectionPool 行为的误解。我猜想,如果没有有关您如何在应用程序中使用池的详细信息。

所以你的池配置如下:

...
poolConfig.setMaxIdle(1);
poolConfig.setMaxTotal(10);
poolConfig.setBlockWhenExhausted(true)
...
Run Code Online (Sandbox Code Playgroud)

这意味着,正如您所期望的,从该特定池到 Redis 的活动连接不会超过 10 个。

您可以使用 RedisInsight 或使用命令CLIENT LIST从 Redis 本身检查客户端(打开的连接)数量,您将看到来自该 JVM 的连接不会超过 10 个。

您看到许多调用的事实getConnection()只是因为您的应用程序每次需要连接时都会调用它。这并不意味着“打开一个新连接”,这意味着“从池中给我一个连接”,并且您的配置定义了行为,如下所示:

  • poolConfig.setMaxIdle(1)=> 您将至少始终有 1 个连接打开并可用于您的应用程序。选择一个好的号码很重要,因为“创建新连接”需要时间和资源。(在正常应用中 1 可能太低)
  • poolConfig.setMaxTotal(10)=> 这意味着池不会同时打开超过 10 个连接。因此,您必须定义当您达到 10 个且您的应用程序需要一个时会发生什么。这是哪里
  • poolConfig.setBlockWhenExhausted(true)=> 这意味着,如果您的应用程序已经使用了 10 个“活动”连接,并且应用程序调用getConnection(),它将“阻塞”,直到 10 个连接之一返回到池中。

所以“阻止”可能不是一个好主意......(但这又取决于您的应用程序)

也许您想知道为什么您的应用程序调用 getConnection() 30 次,以及为什么它不会在 10 次时停止/阻塞......

因为你的代码很好;),我的意思是你的应用程序:

1- Jedis jedis = pool.getCoonnection(); (因此它从池中获取一个活动连接)2-您正在jedis根据需要使用连接3-您关闭连接jedis.close()(这不必关闭真正的连接,它会将连接返回到池中,并且池可以重用它或关闭它,具体取决于应用程序/配置)

是否有意义?

通常您将使用以下代码

...
poolConfig.setMaxIdle(1);
poolConfig.setMaxTotal(10);
poolConfig.setBlockWhenExhausted(true)
...
Run Code Online (Sandbox Code Playgroud)

您可以在此处找到有关 JedisPool 和 Apache CommonPool 的更多信息: