当前位置: 首页 > 知识库问答 >
问题:

为什么我在使用brpop comand的超时选项值(50秒)小于redis command timeout(200s)设置时得到redis命令超时

张光辉
2023-03-14

我使用redis列表作为分布式阻塞队列。在客户端,我使用以下代码:

public String tryAquire(String appName, long timeout, TimeUnit timeUnit){
  return String.valueOf(redisTemplate.opsForList.rightPop(getKey(appName), timeout, timeUnint)); 
}

它使用brpop命令内部,超时值设置为小于50秒。这项服务可以正常工作大约两周,直到最近的最后2天,我有一些例外:

org.springframework.QueryTimeoutException:Redis command time out;
nest exception is io.lettuce.core.RedisCommandException:
Command time out after 200 seconds(s)

该异常每天出现1到2次,每天大约有2000个请求,在此异常之后,服务器仍然工作正常,后续请求的花费时间变得正常,但引发该异常的请求将花费200多秒,这是一个非常糟糕的情况。

这个超时值(200秒)适合我的客户端命令超时设置。

然而,对于tryAquire(appName,timeout,timeUnit)方法,最大阻塞时间设置为小于50秒。因此,这个命令不应该花费超过50秒的时间,因为在50秒后,如果redis列表中没有元素,它应该只返回null,而不是一直等待。似乎没有网络问题,因为日志中没有与套接字相关的异常,并且在redis命令超时异常之后,成功执行了后续请求。

共有1个答案

孔才
2023-03-14

以防有人遇到同样的问题。长话短说:NAT映射过期,在达到最大tcp重试次数后,应用程序会意识到断开的网络链路。

此服务部署在使用自定义SDN的云环境中。如果tcp连接上一段时间没有活动,NAT映射将过期。但是,tcp客户端和服务器都无法意识到这一点,即使NAT映射已过期,客户端也会继续尝试发送数据,直到达到某些tcp重试最大限制配置。

一个简单的解决方案:只要将redis服务器的“tcp keepalive”配置值设置为小于NAT映射过期时间,或者如果不想更改redis服务器设置,则使用任何其他心跳机制。

 类似资料:
  • 问题内容: 我有一个Redis设置键’a’和值‘1’,‘2’,‘3’。是否可以为集合中的每个键值对设置不同的到期时间。 例如,(’a’,‘1’)应该在60秒后过期,而as(’a’,‘2’)应该在120秒后过期。 问题答案: 抱歉不行。Redis的“容器”(即列表,哈希,集合和排序集合)不支持按成员过期,尽管过去多次要求使用此功能。 但是,您可以实现自己的逻辑以实现该结果。解决此问题的方法有几种-

  • 我们已经定义了Lettuce客户端连接工厂,以便能够连接到定义自定义套接字和命令超时的Redis: 莴苣文档定义默认值: 默认套接字超时为10秒 默认命令超时为60秒 如果Redis服务中断,应用程序必须在300ms内接收超时。哪个值必须定义为最大值? Github示例项目:https://github.com/cristianprofile/spring-data-redis-lettuce

  • 我正在学习Hystrix和Clojure,不知道如何(正确地)在Clojure中设置Hystrix命令的超时。 我更广泛地搜索了StackOverflow和web。我查看了Hystrix的Clojure包装器源代码(https://github.com/Netflix/Hystrix/blob/master/hystrix-contrib/hystrix-clj/src/main/clojure/

  • 我使用莴苣客户端作为Redis集群客户端,因为它很好地支持集群Redis。 我遇到过的一个实际问题是在创建客户端时或拓扑刷新时,lettuce会发出“info”命令,这通常比正常的get命令需要更长的时间。设置一般超时,例如10ms,会导致客户端无法启动。 我想知道是否可以根据不同的命令类型设置命令超时。 更新:我已经阅读了源代码,发现我可以编写自己的TimeoutSource来在命令级别设置超时

  • 当微服务处理业务逻辑时间过长,网关会报超时错误,默认等待时间是5秒。 可在网关指定spring.cloud.gateway.httpclient.response-timeout参数设置超时时间,单位毫秒 # 设置响应超时10秒 spring.cloud.gateway.httpclient.response-timeout=10000 更多配置参见:org.springframework.cl

  • <?php $http = HttpRequest::newSession(); $response = $http->timeout(3000, 1000) // 总时间不得超过3秒,连接时间不得超过1秒 ->get('https://www.baidu.com/'); $content = $response->body(); // 网页源码