你的位置:首页 > 信息动态 > 新闻中心
信息动态
联系我们

redis实现分布式锁时用jedis遇到的“Could not get a resource from the pool”总结

2021/12/30 10:14:22

直接长话短说,我自己总结的有以下三点:

1.用完没有释放资源导致卡死

jedis.close();

2.redis连接时的问题,可能是配置文件配错,没有进行redis的配置,或者根本没有连上redis

3.jedis的版本之间的参数会有不同,我当时配置了最大连接数用了max-active这个参数,但是导致了redis Could not get a resource since the pool is exhausted,这个问题,我在代码中请求的是一个1000的循环,我明明设置了1024的最大连接数,资源竟然耗尽了。于是疯狂百度,才发现2.4以后的版本没有max-active这个参数了,改用max-total就可以了。

下面是我redis的properties文件配置以及配置类,可以作参考。

#redis配置开始
# Redis服务器地址
spring.redis.host=127.0.0.1
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=123456
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-total=1024
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=10000
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=1200
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=10000
#redis配置结束
spring.redis.block-when-exhausted=true

@Configuration
@PropertySource("classpath:redis.properties")
@Slf4j
public class RedisConfig {

    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private int port;

    @Value("${spring.redis.timeout}")
    private int timeout;

    @Value("${spring.redis.jedis.pool.max-idle}")
    private int maxIdle;

    @Value("${spring.redis.jedis.pool.max-wait}")
    private long maxWaitMillis;

    @Value("${spring.redis.password}")
    private String password;

    @Value("${spring.redis.jedis.pool.max-total}")
    private int maxTotal;

    @Value("${spring.redis.block-when-exhausted}")
    private boolean  blockWhenExhausted;

    @Bean
    public JedisPool redisPoolFactory()  throws Exception{
        log.info("JedisPool注入成功!!");
        log.info("redis地址:" + host + ":" + port);
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(maxIdle);
        //新版本用maxtotal代替maxactive参数
        jedisPoolConfig.setMaxTotal(maxTotal);
        //新版本没有此参数
        jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
        // 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true
        jedisPoolConfig.setBlockWhenExhausted(blockWhenExhausted);
        // 是否启用pool的jmx管理功能, 默认true
        jedisPoolConfig.setJmxEnabled(true);
        return new JedisPool(jedisPoolConfig, host, port, timeout, password);
    }


}

注意!对于第二点有没有连接上redis,我有一点也觉得很坑,你需要为redis设置密码,我连接的是我本地redis,但是通过命令修改redis密码只在当前redis生效,当redis服务器退出以后就要重新设置了,不然就会爆bug说密码连不上。