如果使用 Feign.Builder 手动创建 Feign 客户端,则不会调用 Hystrix 回退方法

Hystrix fallback method not called if Feign Client manually created with Feign.Builder

我正在尝试创建一个 Feign 客户端,该客户端在失败时具有回退方法。

通过以下示例,我创建了一个简单的 Feign 客户端:

@Component
@FeignClient(value = "authenticationClient", fallback = AuthenticationClientFallback.class)
public interface AuthenticationClient
{
@RequestMapping(method = RequestMethod.GET, value = "/auth/userinfo")
UserInfoResource getUserInfo(@RequestHeader("Authorization") String token);

@RequestMapping(method = RequestMethod.GET, value = "/auth/token")
TokenResource getToken(@RequestHeader("Authorization") String basicAuth);

}

AuthenticaionClientFallback class 如下:

 @Component
    public class AuthenticationClientFallback implements AuthenticationClient
    {
        public static final String NO_TOKEN = "No Token";

        @Override
        public UserInfoResource getUserInfo(String token)
        {
            return null;
        }

        @Override
        public TokenResource getToken(String basicAuth)
        {
            return new TokenResource(NO_TOKEN);
        } 
}

当我将我的客户端与@Autowire 注释一起使用时,回退被触发。但是我需要创建自己的假客户端实例,这样我就可以动态设置 URL.

AuthenticationClient 的初始化:

public AuthenticationClient getAuthenticationClient()
    {
        return HystrixFeign.builder().contract(new SpringMvcContract())
                 .encoder(new JacksonEncoder())
                 .decoder(new JacksonDecoder())
                 .client(new OkHttpClient())
                 .logger(new Slf4jLogger(AuthenticationClient.class))
                 .logLevel(Logger.Level.FULL).target(AuthenticationClient.class, getTargetURL());
    }

现在我的后备方法永远不会被调用,只会抛出一个 FeignException 并返回 401 状态代码的消息。

PS 我在 .yml 文件中设置了 feign.hystrix.enabled=true 并在应用级别设置了 @EnableCircuitBreaker。

我认为你混合了2种伪客户端初始化方法;声明式和手动初始化。你需要坚持一种方法。

如果您使用的是声明式初始化;您可以使用带有后备的@FeignClient 注释,如下所示;

@FeignClient(value = "authenticationClient", url = "${feign.url}", fallback = AuthenticationClientFallback.class)
public interface AuthenticationClient

你可以像这样在你的组件中自动装配假客户端。

@Autowired
AuthenticationClient client;

如果您使用手动初始化 带有一些自定义功能的假客户端;那么您不必在 AuthenticationClient class 上使用 @FeignClient 注释。您可以像下面这样创建自定义的假客户;

@Autowired
AuthenticationClientFallback fallbackClient;

public AuthenticationClient getAuthenticationClient()
    {
        return HystrixFeign.builder().contract(new SpringMvcContract())
                 .encoder(new JacksonEncoder())
                 .decoder(new JacksonDecoder())
                 .client(new OkHttpClient())
                 .logger(new Slf4jLogger(AuthenticationClient.class))
                 .logLevel(Logger.Level.FULL).target(AuthenticationClient.class, getTargetURL(), fallbackClient);
    }

请注意,fallbackClient 对象 作为参数传入 .target()。

有关详细信息,请参阅 Spring 云伪装 documentation