记一次多线程时获取redis连接失败
先上问题:redis.clients.jedis.exceptions.JedisConnectionException: Attempting to read from a broken connectionat redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:274)at redis.c
·
先上问题:
redis.clients.jedis.exceptions.JedisConnectionException: Attempting to read from a broken connection
at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:274)
at redis.clients.jedis.Connection.getIntegerReply(Connection.java:220)
at redis.clients.jedis.Jedis.exists(Jedis.java:213)
at com.cmcc.message.util.JedisUtil.existKey(JedisUtil.java:138)
at com.cmcc.message.util.TokenUtil.getTokenConfig(TokenUtil.java:35)
at com.cmcc.message.consumer.SmsConsumer.process(SmsConsumer.java:68)
at com.cmcc.message.consumer.SmsConsumer$$FastClassBySpringCGLIB$$8503f9d5.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
jedis配置代码:
@Configuration
public class JedisClusterConfig {
private static RedisProperties redisProperties;
private static Jedis jedisCluster = null;
@Autowired
private RedisProperties redisProperties2;
@PostConstruct
public void init() {
redisProperties = redisProperties2;
if (jedisCluster==null) {
try {
jedisCluster = reloadJedisCluster();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 获取JedisCluster对象
*
* @return
* @throws Exception
*/
public static Jedis getCluster() throws Exception {
if (jedisCluster == null) {
synchronized (JedisClusterConfig.class) {
jedisCluster = reloadJedisCluster();
}
return jedisCluster;
} else {
return jedisCluster;
}
}
// public static JedisCluster getJedisCluster(){
// String [] serverArray=redisProperties.getClusterNodes().split(",");
// Set<HostAndPort> nodes=new HashSet<>();
//
// for (String ipPort:serverArray){
// String [] ipPortPair=ipPort.split(":");
// nodes.add(new HostAndPort(ipPortPair[0].trim(),Integer.valueOf(ipPortPair[1].trim())));
//
// }
// String redisAuthPass = redisProperties.getRedisAuthPass();
// return new JedisCluster(nodes,2000, 2000, 6, redisAuthPass, new JedisPoolConfig());
// }
private static Jedis reloadJedisCluster() throws Exception {
System.out.println("初始化实体");
Jedis cluster = null;
String redisAuthPass = redisProperties.getRedisAuthPass();
String addrs = redisProperties.getClusterNodes();
String [] ipPortPair=addrs.split(":");
HostAndPort node = new HostAndPort(ipPortPair[0].trim(), Integer.valueOf(ipPortPair[1].trim()));
cluster = new Jedis(node);
cluster.auth(redisAuthPass);
return cluster;
}
猜测原因:
多线程请求redis获取内容,线程数>2就会报这个错误,百度了一下这个问题,没找到很好的解答。
初步猜测是因为没有使用jedispool,又没有释放连接导致,尝试更新为jedispool。
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
protected static final Logger logger = LoggerFactory.getLogger(RedisConfig.class);
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.jedis.pool.max-active}")
private int maxTotal;
@Value("${spring.redis.jedis.pool.max-idle}")
private int maxIdle;
@Value("${spring.redis.jedis.pool.min-idle}")
private int minIdle;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.timeout}")
private int timeout;
public JedisPool redisPoolFactory() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(maxTotal);
jedisPoolConfig.setMaxIdle(maxIdle);
jedisPoolConfig.setMinIdle(minIdle);
JedisPool jedisPool = null;
if(password == null || password.equals("")){
jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout);
}else{
jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout,password);
}
logger.info("JedisPool注入成功!!");
logger.info("redis地址:" + host + ":" + port);
return jedisPool;
}
}
经测试,报错没再出现。
后续又查看了jedisCluster的源码,发现jediscluster默认可以实现连接池。
遗留问题:
- jedis连接默认释放时间是多少?为什么并发情况下会出现这种异常
更多推荐
已为社区贡献1条内容
所有评论(0)