无法获取Jedis连接,无法从池中获取资源 - java

我正在创建一个Web应用程序,并使用Redis进行数据存储。
我已经使用JedisPoolConfig(redis client-jedis版本2.9.0)。
因此,当我在具有以下配置的Apache Jmeter的帮助下测试我的应用程序时:

Number of threads(Users): 30
Ramp-Up period(in seconds) : 0
Loop-Count : 1

和JedisPoolConfig具有以下配置:

redis.sentinel.enable=true
redis.sentinel.ip=localhost
redis.sentinel.port=6379
redis.instance.account.masterName=master
redis.pool.max-active = 20
redis.pool.max-idle = 10

使用以下代码(在Spring Application启动时作为Bean创建):

JedisConnectionFactory factory = new JedisConnectionFactory();
        factory.setPort(port);
        factory.setHostName(hostName);
        factory.afterPropertiesSet();
        factory.setUsePool(true);
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(redisPoolMaxActive);
        jedisPoolConfig.setMaxIdle(redisPoolMaxIdle);
        factory.setPoolConfig(jedisPoolConfig);
        return factory;

这段代码用于在每次请求到来时获取新的Connection:

@Autowired
private JedisConnectionFactory redisConnectionFactory;
private StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
private RedisTemplate getNewConnection(){
        RedisTemplate redisTemplate = new RedisTemplate();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        redisTemplate.setKeySerializer(stringRedisSerializer);
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        redisTemplate.setValueSerializer(stringRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

编辑:我对Redis里面的multi / exec使用redisTemplate:

redisTemplate.setEnableTransactionSupport(true);

redisTemplate.multi();

for (ArrayList<Pair<String, String>> pairs : keys){
    for (Pair<String,String> pair: pairs)
        redisTemplate.opsForHash().get(makeMap(pair.getFirst(), version) , pair.getSecond());
}

return redisTemplate.exec();

我成功获得了20个请求的响应,但无法获得其余10个请求的响应。我面临的问题是前20个请求使用了20个连接后,其余10个请求无法从池中获取jedis连接,因此出现以下异常:

    2017-10-06 17:38:11.753 ERROR 3539 --- [io-8080-exec-12] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisException: Could not get a resource from the pool] with root cause

java.util.NoSuchElementException: Timeout waiting for idle object
    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:449) ~[commons-pool2-2.4.2.jar:2.4.2]
    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:363) ~[commons-pool2-2.4.2.jar:2.4.2]
    at redis.clients.util.Pool.getResource(Pool.java:49) ~[jedis-2.9.0.jar:na]
    at redis.clients.jedis.JedisPool.getResource(JedisPool.java:226) ~[jedis-2.9.0.jar:na]
    at redis.clients.jedis.JedisPool.getResource(JedisPool.java:16) ~[jedis-2.9.0.jar:na]
    at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:194) ~[spring-data-redis-1.8.6.RELEASE.jar:na]
    at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.getConnection(JedisConnectionFactory.java:348) ~[spring-data-redis-1.8.6.RELEASE.jar:na]
    at org.springframework.data.redis.core.RedisConnectionUtils.doGetConnection(RedisConnectionUtils.java:129) ~[spring-data-redis-1.8.6.RELEASE.jar:na]
    at org.springframework.data.redis.core.RedisConnectionUtils.bindConnection(RedisConnectionUtils.java:67) ~[spring-data-redis-1.8.6.RELEASE.jar:na]
    at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:192) ~[spring-data-redis-1.8.6.RELEASE.jar:na]
    at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:169) ~[spring-data-redis-1.8.6.RELEASE.jar:na]
    at org.springframework.data.redis.core.RedisTemplate.multi(RedisTemplate.java:868) ~[spring-data-redis-1.8.6.RELEASE.jar:na]
    at net.media.mml.redis.repository.RedisRepository.makeTransaction(RedisRepository.java:50) ~[max-data-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
    at net.media.mml.redis.repository.RedisRepository.getFromRedis(RedisRepository.java:66) ~[max-data-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
    at net.media.mml.service.DimensionGetter.getDimensions(DimensionGetter.java:64) ~[ml-api.jar:0.0.1-SNAPSHOT]
    at net.media.mml.service.MLQueriesGetter.makeQueries(MLQueriesGetter.java:32) ~[ml-api.jar:0.0.1-SNAPSHOT]
    at net.media.mml.controller.MaxQueryController.query(MaxQueryController.java:61) ~[ml-api.jar:0.0.1-SNAPSHOT]
    at sun.reflect.GeneratedMethodAccessor270.invoke(Unknown Source) ~[na:na]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_131]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_131]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE]

我已经在网上搜索了,但是找不到解决方案。有谁能够帮我?

java大神给出的解决方案

使用Redis事务需要在回调中进行调用。 setEnableTransactionSupport(true)供事务管理器/ @Transactional使用。有关更多详细信息,请参见reference documentation。

除非您有交易管理器,否则不要使用setEnableTransactionSupport(true)

您的代码应如下所示:

List<Object> txResults = redisTemplate.execute(new SessionCallback<List<Object>>() {
  public List<Object> execute(RedisOperations operations) throws DataAccessException {
    operations.multi();
    operations.opsForSet().add("key", "value1");

    // This will contain the results of all ops in the transaction
    return operations.exec();
  }
});

bulit-in gradle插件的版本号是多少? - java

在我的gradle构建文件中,我有以下插件块plugins { `java-library` jacoco checkstyle } 这些都没有指定版本,但是一切正常。假定一个项目正在使用gradle 6.0和gradle包装器,但是系统已安装gradle 5.0。问题:如果我运行gradle wrapper ./gradlew build,将会执行grad…

“公共静态最终长USER_ACCOUNT = 32L”是什么意思?后缀L在long变量中意味着什么? - java

我在这里找到了代码片段public static final long USER_ACCOUNT = 32L; 32L在这里是什么意思?这是否意味着仅具有数字值long的32变量还是意味着long将需要32位值?如果我不提供后面的L数字32结尾怎么办? java大神给出的解决方案 在Java中编写长文字时,需要使用“ L”后缀。 (您可以使用小写的“ l”,…

DataSourceTransactionManager和JndiObjectFactoryBean和JdbcTemplate的用途是什么? - java

以下的用途是什么:org.springframework.jdbc.core.JdbcTemplate org.springframework.jdbc.datasource.DataSourceTransactionManager org.springframework.jndi.JndiObjectFactoryBean <tx:annotatio…

Java API中是否有等效于.Net框架的Random.Next(Int32,Int32)? - random

我正在将现有的VB.Net应用程序移植到Java,找不到与Random.Next(Int32,Int32)等效的文件。我在Java API中只能找到java.util.Random.next(int val)。Java API中是否有等效于.Net框架的Random.Next(Int32,Int32)? random大神给出的解决方案 正如Marc所说,只需…