最近线上经常报错,错误如下
线上环境springboot 2.3.3 Jedis 2.9.1
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
......
Caused by: redis.clients.jedis.exceptions.JedisConnectionException: Failed connecting to host redis-xxx.
com:
6379
......
Caused by: java.net.SocketTimeoutException: connect timed out
但是测试环境正常,没有报错。
初步是怀疑线上并发高,连接池满了,尝试增加连接池配置,无果。
------------------------------------------------------------------------
解决方案:
通过排查发现Jedis 2.9.1 一直有这个bug。将Jedis版本升级到3.3.0
工具类修改如下:
@Configuration
public class JedisUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(JedisUtil.class);
@Bean
@ConfigurationProperties(prefix = "spring.redis")
public JedisPool getJedisPool() {
if (jedisPool == null) {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(20);
config.setMaxIdle(20);
config.setMinIdle(5);
config.setMaxWaitMillis(10000);
config.setTestOnBorrow(true);
config.setTestOnReturn(true);
//Idle时进行连接扫描
config.setTestWhileIdle(true);
//表示idle object evitor两次扫描之间要sleep的毫秒数
config.setTimeBetweenEvictionRunsMillis(30000);
//表示idle object evitor每次扫描的最多的对象数
config.setNumTestsPerEvictionRun(10);
//表示一个对象至少停留在idle状态的最短时间,然后才能被idle object evitor扫描并驱逐;这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义
config.setMinEvictableIdleTimeMillis(60000);
if (StringUtils.isEmpty(jedisPassword)) {
jedisPool = new JedisPool(config
, jedisIP
, jedisPort, 60000);
} else {
jedisPool = new JedisPool(config
, jedisIP
, jedisPort, 60000, jedisPassword);
}
}
return jedisPool;
}
@Value("${spring.redis.host}")
private String jedisIP;
@Value("${spring.redis.port}")
private int jedisPort;
@Value("${spring.redis.password}")
private String jedisPassword;
private static JedisPool jedisPool;
/**
* 获取数据
*/
public static String get(String key) {
String value = null;
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
value = jedis.get(key);
} catch (Exception e) {
LOGGER.error("JedisUtil get error", e);
} finally {
if (null != jedis) {
jedis.close();
}
}
return value;
}
/**
* 删除key
*/
public static void del(String key) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
jedis.del(key);
} catch (Exception e) {
LOGGER.error("JedisUtil del error", e);
} finally {
//返还到连接池
if (null != jedis) {
jedis.close();
}
}
}
/**
* 设置过期时长
*
* @param key
* @param seconds 秒
* @param value
*/
public static boolean setex(String key, int seconds, String value) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
jedis.setex(key, seconds, value);
return true;
} catch (Exception e) {
LOGGER.error("JedisUtil setex error", e);
return false;
} finally {
//返还到连接池
if (null != jedis) {
jedis.close();
}
}
}
}
修改完成后上线,观察了几天,没有再报错,自此问题解决。
springboot 2.3.3 本身是管理的有Jedis的版本,就是3.3.0,我们在开发中如果需要springboot集成到其他的组件,最好是使用springboot自带管理的版本,尽量不要手动去指定组件版本,
不然很容易出现兼容问题。
MARK:
最近在关注一个手机挖矿项目,叫Bee蜜蜂币。
APP 下载链接: https://bee.com/sc/
推荐码:lei911gang
手机免费挖矿,感兴趣的可以一起加入。