我应该总是在业务逻辑结束时调用 jedis 实例的关闭吗?

问题描述

我使用 jedis 作为带有弹簧靴的 redis 连接。

jedis 池配置如下:

@Configuration
@ConditionalOnClass(JedisPool.class)
@EnableConfigurationProperties(JedisProperties.class)
public class JedisAutoConfiguration {
    private JedisProperties jedisProperties;
    
    public JedisAutoConfiguration(JedisProperties jedisProperties) {
        this.jedisProperties = jedisProperties;
    }
    
    @Bean
    @ConditionalOnMissingBean(JedisPool.class)
    public JedisPool jedisPool() {
        
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxIdle(jedisProperties.getPool().getMaxIdle());
        poolConfig.setMaxTotal(jedisProperties.getPool().getMaxTotal());
        poolConfig.setMaxWaitMillis(jedisProperties.getPool().getMaxWaitMillis() * 1000);
        
        JedisPool jedisPool = new JedisPool(poolConfig,jedisProperties.getHost(),jedisProperties.getPort(),jedisProperties.getTimeout()*1000,jedisProperties.getpassword(),0);
        return jedisPool;
    }
}

每次需要连接redis的时候,我都会从jedis pool租一个资源:

@Service
public class UserService   {

    
    @Autowired
    private JedisPool jedisPool;


    public User FindUserFromCache(Integer id){
        Jedis resource  = jedisPool.getResource()
        // business logic

        // resource.close()
    }

}

问题:

1.我应该在业务逻辑结束时将资源返回到池中吗? spring boot 或 java 运行时能自动处理这种情况吗?

2.如果资源没有关闭,那么资源将永远不会回到池中?

解决方法

是否应该在业务逻辑结束时将资源返回到池中?

是的。

您也可以使用 Java 的 try-with-resources 功能。

    try (Jedis resource  = jedisPool.getResource()) {
        // business logic
    }

spring boot 或 java runtime 能不能自动处理这种情况?

JedisPool 基于 Apache commons-pool2 项目,它既不属于 spring(引导)也不属于核心 java。所以这些不能/不自动处理这种情况。

如果资源没有关闭,那么资源将永远不会返回到池中?

准确地说,如果资源没有返回,那么它就永远不会回到池中。还有其他方法可以将资源返回到池中。但 close() 应该是用户友好的方式。

,

与其直接使用 Jedis 连接池,不如使用 RedisTemplate

这样,您就不会为在业务逻辑代码中释放 Jedis 连接资源而烦恼。意味着更好的抽象。

此外,您将来可以将驱动程序从“Jedis”更改为更新的“Lettuce”,而无需更改您的业务逻辑。

在此处查看更多信息:https://docs.spring.io/spring-data/data-redis/docs/current/reference/html/#redis:template