如何解决FeignClient的超时问题

37

当使用FeignClient调用执行SQL Server查询的服务时,我的应用程序出现以下错误。

ERROR:

Exception in thread "pool-10-thread-14" feign.RetryableException: Read timed out executing GET http://127.0.0.1:8876/processoData/search/buscaProcessoPorCliente?cliente=ELEKTRO+-+TRABALHISTA&estado=SP

我的消费者服务:

@FeignClient(url="http://127.0.0.1:8876")
public interface ProcessoConsumer {

@RequestMapping(method = RequestMethod.GET, value = "/processoData/search/buscaProcessoPorCliente?cliente={cliente}&estado={estado}")
public PagedResources<ProcessoDTO> buscaProcessoClienteEstado(@PathVariable("cliente") String cliente, @PathVariable("estado") String estado);

}

我的YML:

server:
  port: 8874

endpoints:
  restart:
    enabled: true
  shutdown:
    enabled: true
  health:
    sensitive: false

eureka:
  client:
  serviceUrl:
    defaultZone: ${vcap.services.eureka-service.credentials.uri:http://xxx.xx.xxx.xx:8764}/eureka/
  instance: 
    preferIpAddress: true

ribbon:
  eureka:
    enabled: true

spring:
  application:
    name: MyApplication
  data:
    mongodb:
      host: xxx.xx.xxx.xx
      port: 27017
      uri: mongodb://xxx.xx.xxx.xx/recortesExtrator
      repositories.enabled: true
    solr:
      host: http://xxx.xx.xxx.xx:8983/solr
      repositories.enabled: true

有人知道如何解决这个问题吗?

谢谢。


嘿Renan,你在什么时间会出现超时错误,调用后端通常需要多长时间? - daniel.eichten
为什么你的Feign客户端显示端口8876,但你的YML配置文件却显示端口8874? - psantamaria
10个回答

52
将以下属性添加到application.properties文件中,单位为毫秒。
feign.client.config.default.connectTimeout=160000000
feign.client.config.default.readTimeout=160000000

2
在尝试了各种包括Hystrix、ribbon等属性的黑魔法后,这是我遇到的最干净(且可行)的解决方案。 - Abhishek Prabhat
14
注意:为了使内容更加通俗易懂,本翻译做出了略微的调整。关键是这两个设置必须同时进行才能生效。以下是相关来源 - kadam
3
我遇到了同样的问题,只有在设置了这两个属性后才修复了超时问题。 另一个提示是,您可以将“_default_”单词替换为API feignName,以针对不同的API配置不同的超时时间,具体描述请参见此处 - dbaltor

16

我正在使用Feign.builder()实例化我的Feign客户端。

为了设置connectTimeoutreadTimeout,我使用以下代码:

Feign.builder()
     ...
     .options(new Request.Options(connectTimeout, readTimeout))
     .target(MyApiInterface.class, url);

使用此功能,我可以为不同的API配置不同的超时时间。


3
这个 .options 已经被弃用了,最好使用新的 .options(new Request.Options(CONNECTION_TIME_OUT_IN_SEC, TimeUnit.SECONDS,CONNECTION_TIME_OUT_IN_SEC, TimeUnit.Seconds, true))。最后一个参数是用于跟随重定向。您可以根据提供的单位给出任何超时值。 - im_bhatman

9

我也遇到了这个问题。根据@spencergibb的建议,这是我正在使用的解决方法。请参见链接

在application.properties中添加以下内容。

# Disable Hystrix timeout globally (for all services)
hystrix.command.default.execution.timeout.enabled: false

# Increase the Hystrix timeout to 60s (globally)
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 60000

将以下内容添加到Java配置类中。

import feign.Request;

@Configuration
@EnableDiscoveryClient
@EnableFeignClients(basePackageClasses = { ServiceFeignClient.class })
@ComponentScan(basePackageClasses = { ServiceFeignClient.class })
public class FeignConfig {

    /**
     * Method to create a bean to increase the timeout value, 
     * It is used to overcome the Retryable exception while invoking the feign client.
     * @param env,
     *            An {@link ConfigurableEnvironment}
     * @return A {@link Request}
     */
    @Bean
    public static Request.Options requestOptions(ConfigurableEnvironment env) {
        int ribbonReadTimeout = env.getProperty("ribbon.ReadTimeout", int.class, 70000);
        int ribbonConnectionTimeout = env.getProperty("ribbon.ConnectTimeout", int.class, 60000);

        return new Request.Options(ribbonConnectionTimeout, ribbonReadTimeout);
    }
}

1
谢谢。我不使用Hystrix,而且所有建议使用ribbon.Read和Connect Timeout都对我没有用。但是添加这个bean解决了问题。 - Vuk Djapic

2

对于使用spring-cloud-starter-openfeign的人:

spring.cloud.openfeign.client.config.default.readTimeout=5000 spring.cloud.openfeign.client.config.default.connect-timeout=5000


2
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=6000
ribbon.ReadTimeout=60000
ribbon.ConnectTimeout=60000

确保Ribbon的超时时间大于Hystrix。


10
应该完全相反: 当使用包装Ribbon客户端的Hystrix命令时,您需要确保您的Hystrix超时时间配置要比配置的Ribbon超时时间长,包括可能进行的任何重试。例如,如果您的Ribbon连接超时是1秒,而Ribbon客户端可能会重试三次请求,则您的Hystrix超时时间应略长于3秒。 - Alexander Palamarchuk
更新了@AlexanderPalamarchuk评论中的源链接: https://cloud.spring.io/spring-cloud-netflix/multi/multi__hystrix_timeouts_and_ribbon_clients.html - dbaltor

1
你可以在你的方法中添加“选项”参数,动态控制超时时间。
@FeignClient(url="http://127.0.0.1:8876")
public interface ProcessoConsumer {
    @RequestMapping(method = RequestMethod.GET, value = "/processoData/search/buscaProcessoPorCliente?cliente={cliente}&estado={estado}")
    PagedResources<ProcessoDTO> buscaProcessoClienteEstado(@PathVariable("cliente") String cliente, @PathVariable("estado") String estado,
                                                                  Request.Options options);
}

使用方法如下:

processoConsumer.buscaProcessoClienteEstado(..., new Request.Options(100, TimeUnit.MILLISECONDS,
        100, TimeUnit.MILLISECONDS, true));

0
请在application.properties文件中添加以下属性:

值5000表示毫秒

feign.client.config.default.connectTimeout: 5000
feign.client.config.default.readTimeout: 5000

这是一个重复的最受欢迎答案的副本。 - undefined

-2

1
这本质上是一个仅包含链接的回答。 - Stephen C

-3

eureka: client: eureka-server-read-timeout-seconds: 30

意思是:eureka客户端,eureka服务器读取超时时间为30秒。

-4

将以下内容添加到application.properties文件中

feign.hystrix.enabled=false hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接