【问题标题】:Could redisTemplate.executePipelined cause SocketTimeOutredisTemplate.executePipelined 可能导致 SocketTimeOut
【发布时间】:2020-08-24 02:10:24
【问题描述】:

这是我的代码:

redisTemplate.executePipelined(new SessionCallback<Object>() {
    @Override
    public Object execute(RedisOperations redisOperations) throws DataAccessException {
        redisTemplate.opsForSet().add(e, businessCode);
        return null;
    }
});

内码“redisTemplate.opsForSet().add(e, businessCode);”正在使用一个连接

感谢回答

补充堆栈错误信息:

org.springframework.data.redis.RedisConnectionFailureException: java.net.SocketTimeoutException: Read timed out; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out
    at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:67)
    at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:41)
    at org.springframework.data.redis.PassThroughExceptionTranslationStrategy.translate(PassThroughExceptionTranslationStrategy.java:37)
    at org.springframework.data.redis.FallbackExceptionTranslationStrategy.translate(FallbackExceptionTranslationStrategy.java:37)
    at org.springframework.data.redis.connection.jedis.JedisConnection.convertJedisAccessException(JedisConnection.java:241)
    at org.springframework.data.redis.connection.jedis.JedisConnection.zRange(JedisConnection.java:2348)
    at org.springframework.data.redis.connection.DefaultStringRedisConnection.zRange(DefaultStringRedisConnection.java:1058)
    at org.springframework.data.redis.core.DefaultZSetOperations$5.doInRedis(DefaultZSetOperations.java:101)
    at org.springframework.data.redis.core.DefaultZSetOperations$5.doInRedis(DefaultZSetOperations.java:98)
    at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:207)
    at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:169)
    at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:91)
    at org.springframework.data.redis.core.DefaultZSetOperations.range(DefaultZSetOperations.java:98)
    at com.*.mshop.reach.service.impl.ReachServiceImpl.query(ReachServiceImpl.java:178)
    at com.*.mshop.reach.service.impl.ReachServiceImpl$$FastClassBySpringCGLIB$$633d23e1.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:667)
    at com.*.mshop.reach.service.impl.ReachServiceImpl$$EnhancerBySpringCGLIB$$486aa953.query(<generated>)
    at com.*.mshop.facade.controller.ReachControllerImpl.query$original$1525E0bP(ReachControllerImpl.java:174)
    at com.*.mshop.facade.controller.ReachControllerImpl.query$original$1525E0bP$accessor$dcQnJrPQ(ReachControllerImpl.java)
    at com.*.mshop.facade.controller.ReachControllerImpl$auxiliary$jZ0njKo2.call(Unknown Source)
    at org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstMethodsInter.intercept(InstMethodsInter.java:86)
    at com.*.mshop.facade.controller.ReachControllerImpl.query(ReachControllerImpl.java)
    at com.*.mshop.facade.controller.ReachControllerImpl.queryCommodity$original$1525E0bP(ReachControllerImpl.java:203)
    at com.*.mshop.facade.controller.ReachControllerImpl.queryCommodity$original$1525E0bP$accessor$dcQnJrPQ(ReachControllerImpl.java)
    at com.*.mshop.facade.controller.ReachControllerImpl$auxiliary$NkOmWqfY.call(Unknown Source)
    at org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstMethodsInter.intercept(InstMethodsInter.java:86)
    at com.*.mshop.facade.controller.ReachControllerImpl.queryCommodity(ReachControllerImpl.java)
    at com.*.mshop.facade.controller.ReachControllerImpl$$FastClassBySpringCGLIB$$c8f1c1b6.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)

在这个异常调用executePipelined 之前,大约1 分钟,无法获得redis 连接。

redis 连接池配置:

spring.redis.pool.max-active = 2000
spring.redis.pool.max-wait = 5000
spring.redis.pool.max-idle = 200
spring.redis.pool.min-idle = 10
spring.redis.timeout = 0

【问题讨论】:

  • 有点不清楚你在问什么。您是在询问 SocketTimeOut 异常还是您的 redisTemplate 是否正在使用连接池?
  • 是 SocketTimeOut 异常,我的 redis 连接池配置是:spring.redis.pool.max-active = 2000 spring.redis.pool.max-wait = 5000 spring.redis.pool.max-idle = 200 spring.redis.pool.min-idle = 10 spring.redis.timeout = 0
  • 不过,这个问题到底是什么?使用该配置,我希望连接池处于活动状态,但它开始时没有连接。所以当你第一次尝试做某事时,它会尝试连接,这可能会导致连接超时。

标签: java redis spring-data-redis


【解决方案1】:

Redis Pipeline 对 Jedis 和 Lettuce 有不同的实现。

在 Jedis 中,管道会阻塞 1 个连接,并将所有管道命令与同一个连接(bio)一起发送

在 Lettuce 中,管道使用 Netty nio 作为网络连接工具。所以在客户端执行管道的过程中,它不会阻塞连接(通常生菜会使用单连接)。并且当 pipeline 执行(发送到 Redis)时,它会从 Netty 中选择 1 个连接。

并且两个库都对管道命令使用相同的连接,因为它们将在单个网络请求中一起发送所有命令。

【讨论】:

  • 所以可能会创建多个管道导致阻塞,我确实在我的代码中创建了多个管道。这个管道是延迟发送吗?我的日志显示确认是在一分钟前。 socketTimeOut 1分钟后发生
  • 同步管道后会立即发送到 RedisClient。但是如果连接池已满(Jedis 使用 block io,它会阻塞每个命令的连接),它会等到下一个可用连接。
猜你喜欢
  • 2011-08-26
  • 1970-01-01
  • 1970-01-01
  • 2011-02-19
  • 1970-01-01
  • 1970-01-01
  • 2011-11-13
  • 1970-01-01
相关资源
最近更新 更多