Springboot集成Redis测试之踩坑(一)
遇到的问题是报错:
org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:281)
at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.getConnection(JedisConnectionFactory.java:464)
at org.springframework.data.redis.core.RedisConnectionUtils.doGetConnection(RedisConnectionUtils.java:132)
at org.springframework.data.redis.core.RedisConnectionUtils.getConnection(RedisConnectionUtils.java:95)
at org.springframework.data.redis.core.RedisConnectionUtils.getConnection(RedisConnectionUtils.java:82)
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:211)
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:184)
at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:95)
at org.springframework.data.redis.core.DefaultValueOperations.set(DefaultValueOperations.java:236)
at com.test.demo.test.TestRedis.redis(TestRedis.java:25)
at com.test.demo.test.Test.get(Test.java:29)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
at redis.clients.util.Pool.getResource(Pool.java:53)
at redis.clients.jedis.JedisPool.getResource(JedisPool.java:226)
at redis.clients.jedis.JedisPool.getResource(JedisPool.java:16)
at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:271)
... 40 more
Caused by: redis.clients.jedis.exceptions.JedisDataException: ERR invalid DB index
at redis.clients.jedis.Protocol.processError(Protocol.java:130)
at redis.clients.jedis.Protocol.process(Protocol.java:164)
at redis.clients.jedis.Protocol.read(Protocol.java:218)
at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:341)
at redis.clients.jedis.Connection.getStatusCodeReply(Connection.java:240)
at redis.clients.jedis.BinaryJedis.select(BinaryJedis.java:541)
at redis.clients.jedis.JedisFactory.makeObject(JedisFactory.java:111)
at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:874)
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:417)
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:346)
at redis.clients.util.Pool.getResource(Pool.java:49)
... 43 more
我的代码实现:配置类
/**
* Created on 2019/3/31.
* Title: Simple
* Description:配置類
* Copyright: Copyright(c) 2019
* Company:
*
* @author wy
*/
@Configuration
@Slf4j
public class RedisConfig {
@Value("${redis.host}")
private String host;
@Value("${redis.port}")
private Integer port;
@Value("${redis.password}")
private String password;
@Value("${redis.index}")
private Integer index;
@Value("${redis.timeout}")
private int timeout;
@Value("${redis.pool.max-total}")
private int maxTotal;
@PostConstruct
public void init()
{
log.info("ids redis host {}, port {}", this.host, this.port);
}
@Primary
@Bean(name="redisConnectionFactory")
public JedisConnectionFactory idsRedisConnectionFactory() {
if (StringUtil.isBlank(this.host)) {
log.info("No need to initialize ids redis.");
return null;
}
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setHostName(this.host);
factory.setPort(this.port);
factory.setDatabase(this.index);
factory.setTimeout(this.timeout);
factory.setUsePool(true);
if (StringUtil.isNotBlank(this.password)) {
factory.setPassword(this.password);
log.info("idsRedisConnectionFactory setPassword {}", this.password);
}
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(this.maxTotal);
factory.setPoolConfig(jedisPoolConfig);
return factory;
}
@Primary
@Bean(name="idsRedisTemplate")
public RedisTemplate<String, String> idsRedisTemplate(@Qualifier("redisConnectionFactory")
RedisConnectionFactory cacheRedisConnectionFactory) {
if (null == cacheRedisConnectionFactory) {
return null;
}
StringRedisTemplate template = new StringRedisTemplate(cacheRedisConnectionFactory);
template.afterPropertiesSet();
log.warn("set ids redis {}:{}", this.host, this.port);
return template;
}
}
读取配置文件配置:
#redis
redis:
host: 127.0.0.1
port: 6379
password:
timeout: 2000
index: 31
pool:
max-active: 8
max-idle: 8
max-wait: -1
min-idle: 0
max-total: 10
开始在前面几次进行测试的时候,运行了几次,因为连接池的数量很小,现在我定位应该是产生异常导致连接资源没有释放的问题,这个问题的解决方案,关于springboot和redis的版本问题方案已经测试过,更换了,还是不好使,连接池数量调大也是不行。
目前定位到了这个问题的解决方案,就是配置类的位置进行加载了一个配置源导致的读取失败,这个加载的是Redis的库,由于是在本地进行测试,所以肯定不会从池中获取到的连接资源,这属于个人忽略陪配置类的问题,虽然是小问题,但是代码实现还是要上心的,要仔细:这是自己测试的时候发现的问题,但是如果在项目当中就存在项目使用哪个redis库的问题,这种情况下,这个配置可以存在的。