在 HystrixFeign 客户端回退中获取原因的问题

Posted

技术标签:

【中文标题】在 HystrixFeign 客户端回退中获取原因的问题【英文标题】:Issue in getting cause in HystrixFeign client fallback 【发布时间】:2017-01-15 15:03:00 【问题描述】:

我有 HystrixFeign 客户端,我正在尝试在我的回退实现中获取原因/异常,因为我真的很想知道回退的原因,以便我可以解决服务调用失败的问题。 但是下面的实现并没有让我明白原因。这工作得很好,并且回退一直被调用。但我不知道为什么。我是 Feign 和 Hystrix 的新手。我的应用程序是 1.6 年前用 java 编写的,这是一种增强调用。所以我不能使用任何 lambda 表达式。

我有如下定义的客户端接口

public interface MyServiceFeignClient 
      @RequestLine("POST /myService/order")
      @Headers("Content-Type:application/vnd.org.company.domain.order+json;version=1.0")
      ServiceResponse sendOrder(String content);

我的 FeignClientFacory 如下所示

public class FeignClientFactory 

    private static final Logger LOG = LoggerFactory.getLogger(FeignClientFactory.class);

    private String serviceUrl;

    public FeignClientFactory(final String serviceUrl) 
        this.serviceUrl = serviceUrl;
    

    public MyServiceFeignClient newInstance() 
        return HystrixFeign.builder()
            .decoder(new GsonDecoder())
            .target(MyServiceFeignClient.class, serviceUrl);

    

    class ClientFallbackFactory implements MyServiceFeignClient, FallbackFactory<ClientFallbackFactory> 

        final Throwable cause;

        public ClientFallbackFactory() 
            this(null);
        

        ClientFallbackFactory(Throwable cause) 
            this.cause = cause;
        
        // note that this method is not getting called at all
        @Override
        public ClientFallbackFactory create(Throwable cause) 
            if (cause != null) 
                String errMessage = StringUtils.isNotBlank(cause.getMessage()) ? cause.getMessage() : "unknown error occured";
                LOG.debug("Client fallback called for the cause : ", errMessage);
            
            return new ClientFallbackFactory(cause);

        
        // everytime this method is called as fallback and the cause is just null
        @Override
        public ServiceResponse sendOrder(String content) 
            LOG.debug("service client api fallback called");
            ServiceResponse response = new ServiceResponse();
            String errMessage = (cause == null ? "service client api fallback called" : cause.getMessage());
            response.setErrorMessage(errMessage);
            response.setResultStatus("WARN");
            return response;
        

    


【问题讨论】:

【参考方案1】:

从打开的 feign git hub 获取 retroApi 示例测试用例代码并开始一一修改帮助我解决了这个问题。下面是工作代码。

public static class ClientFallbackFactory implements MyServiceFeignClient, FallbackFactory<ClientFallbackFactory> 

    @Override
    public ClientFallbackFactory create(Throwable cause) 
        return new PRSClientFallback(cause);
    

    final Throwable cause; // nullable

    public ClientFallbackFactory() 
        this(null);
    

    ClientFallbackFactory(Throwable cause) 
        this.cause = cause;
    

    @Override
    public PaymentRiskServiceResponse sendOrder(String content) 
        String errorMessage = (cause == null) ? "No cause returned" : cause.getMessage();
        LOG.debug("Client fallback called :  ", errorMessage);
        MyServiceResponse response = new MyServiceResponse();
        response.setResultStatus("WARN");
        response.setErrorMessage("Client fallback called");
        return response;
    

确保在调用 HystrixFeign 目标方法时对 Fallback 工厂进行类型转换,因为 Fallback 类同时实现了您的客户端接口和 FallbackFactory。

return HystrixFeign.builder()
        .encoder(new JacksonEncoder(mapper))
        .decoder(new GsonDecoder())
        .target(MyServiceFeignClient.class, prsUrl, (FallbackFactory<ClientFallbackFactory>) new ClientFallbackFactory());

您可以跟踪此问题的对话 [https://github.com/OpenFeign/feign/issues/458]

【讨论】:

以上是关于在 HystrixFeign 客户端回退中获取原因的问题的主要内容,如果未能解决你的问题,请参考以下文章

CSS calc 在 Safari 和回退中不起作用

在@HystrixCommand 回退方法中获取失败异常

网络文件系统挂载,本地回退?

feign + hystrix 降级

使用 Hystrix Feign 记录请求和响应 json 有效负载

如何强制客户端使用 http/2? (而不是回退到 http 1.1)