添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
直爽的饭盒  ·  5. Hystrix Timeouts ...·  1 周前    · 
沉着的沙滩裤  ·  【feign】SpringCloud ...·  4 月前    · 
瘦瘦的青蛙  ·  管理接口 — envoy ...·  5 月前    · 
没读研的大葱  ·  无人生还_百度百科·  1 月前    · 
瘦瘦的刺猬  ·  Spring app on wildfly ...·  1 月前    · 

最近在项目开发中,使用 Feign 调用服务,当触发熔断机制时,遇到了以下问题:

  • 异常信息形如: TestService#addRecord(ParamVO) failed and no fallback available.
  • 获取不到服务提供方抛出的原始异常信息;
  • 实现某些业务方法不进入熔断,直接往外抛出异常;

接下来将一一解决上述问题。

对于 failed and no fallback available. 这种异常信息,是因为项目开启了熔断:

feign.hystrix.enabled: true
@EnableCircuitBreaker

当调用服务时抛出了异常,却没有定义fallback方法,就会抛出上述异常。由此引出了第一个解决方式。

@FeignClient加上fallback方法,并获取异常信息

@FeignClient修饰的接口加上fallback方法有两种方式,由于要获取异常信息,所以使用fallbackFactory的方式:

@FeignClient(name = "hello", fallbackFactory = HystrixClientFallbackFactory.class)
protected interface HystrixClient {
    @RequestMapping(method = RequestMethod.GET, value = "/hello")
    Hello iFailSometimes();

@FeignClient注解中指定fallbackFactory,上面例子中的HystrixClientFallbackFactory如下:

@Component
static class HystrixClientFallbackFactory implements FallbackFactory<HystrixClient> {
    @Override
    public HystrixClient create(Throwable cause) {
        return new HystrixClient() {
            @Override
            public Hello iFailSometimes() {
                return new Hello("fallback; reason was: " + cause.getMessage());

通过实现FallbackFactory,可以在create方法中获取到服务抛出的异常。但是请注意,这里的异常是被Feign封装过的异常,不能直接在异常信息中看出原始方法抛出的异常。

保留原始异常信息

当调用服务时,如果服务返回的状态码不是200,就会进入到FeignErrorDecoder中,因此如果我们要解析异常信息,就要重写ErrorDecoder

public class KeepErrMsgConfiguration {
    @Bean
    public ErrorDecoder errorDecoder() {
        return new RawErrorDecoder();
    public class RawErrorDecoder implements ErrorDecoder {
		@Override
        public Exception decode(String methodKey, Response response) {
            String message = null;
            try {
                if (response.body() != null) {
				    // 获取原始的返回内容
                    message = Util.toString(response.body().asReader(Util.UTF_8));
					// 将返回内容反序列化为Result,这里应根据自身项目作修改
                    JSONObject json = JSONObject.parseObject(message);
                    return new RuntimeException(json.getString("message"));
            } catch (Exception ignored) {
            return new RuntimeException(message);

上面是一个例子,原理是根据response.body()反序列化为自定义的Result类,提取出里面的message信息,然后抛出RuntimeException,这样当进入到熔断方法中时,获取到的异常就是我们处理过的RuntimeException

注意上面的例子并不是通用的,但原理是相通的,大家要结合自身的项目作相应的修改。

要使上面代码发挥作用,还需要在@FeignClient注解中指定configuration

@FeignClient(name = "hello", fallbackFactory = HystrixClientFallbackFactory.class, configuration = LogFeignConfiguration.class)
protected interface HystrixClient {
    @RequestMapping(method = RequestMethod.GET, value = "/hello")
    Hello iFailSometimes();

不进入熔断,直接抛出异常

有时我们并不希望方法进入熔断逻辑,只是把异常原样往外抛。这种情况我们只需要捉住两个点:不进入熔断、原样

原样就是获取原始的异常,上面已经介绍过了,而不进入熔断,需要把异常封装成HystrixBadRequestException,对于HystrixBadRequestExceptionFeign会直接抛出,不进入熔断方法。

因此我们只需要在上述KeepErrMsgConfiguration的基础上作一点修改即可:

public class NotBreakerConfiguration {
    @Bean
    public ErrorDecoder errorDecoder() {
        return new RawErrorDecoder();
    public class RawErrorDecoder implements ErrorDecoder {
		@Override
        public Exception decode(String methodKey, Response response) {
            String message = null;
            try {
                if (response.body() != null) {
                    message = Util.toString(response.body().asReader(Util.UTF_8));
                    JSONObject json = JSONObject.parseObject(message);
                    // 业务异常包装成 HystrixBadRequestException,不进入熔断逻辑
                    return new HystrixBadRequestException(json.getString("message"));
            } catch (Exception ignored) {
            return new HystrixBadRequestException(message);

为了更好的达到熔断效果,我们应该为每个接口指定fallback方法。而根据自身的业务特点,可以灵活的配置上述的KeepErrMsgConfigurationNotBreakerConfiguration,或自己编写Configuration

以上例子特殊性较强,不足之处请不吝指教。希望大家可以从中获取到有用的东西,应用到自己的项目中,感谢阅读。

文章目录问题`@FeignClient`加上`fallback`方法,并获取异常信息保留原始异常信息不进入熔断,直接抛出异常总结问题最近在项目开发中,使用 Feign 调用服务,当触发熔断机制时,遇到了以下问题:异常信息形如:TestService#addRecord(ParamVO) failed and no fallback available.;获取不到服务提供方抛出的原始异常信息;实现某些业务方法不进入熔断,直接往外抛出异常;接下来将一一解决上述问题。对于failed and n
Spring Cloud OpenFeign 示例代码工程。该工程基于官方示例(https://github.com/spring-cloud-samples/feign-eureka),额外添加了注册中心模块feign-eureka-central(eureka is running on http://localhost:8761)。官方示例工程jdk代码环境为jdk-17,由于我本地环境为jdk-8,所以调整了示例工程中的依赖版本信息,使示例工程能在jdk-8的环境下正常运行。本示例在官方示例的基础上,添加了FeignClient初始化的方式,共计2种供参考,名称为:FeignClientWarmup、LoadBalancerClientsInitializer,主要解决FeignClient客户端第一次调用慢问题,详细说明参见feign-eureka工程中feign-eureka-hello-client模块。
使用feign client进行restful服务间的调用,除了要注意超时时间、retry的设置外,还有一个关于自定义异常的部分,需要注意一下,不然容易出错。 nginx对于upstream的health check Nginx 默认判断失败节点状态以connect refuse和time out状态为准,不以HTTP错误状态进行判断...
开发中,A服务调用B服务时,B服务中参数校验未通过抛出了自定义异常,错误码是10001,错误消息时“XXXXX不能为空”,返回到A服务时,A服务无法获取到错误码10001。 OpenFeignFeignException返回的异常信息默认status为500。导致10001code丢失。每个服务的自定义异常可能不一样,不过无所谓,主要是异常时获取code和message并透传到前端。 自定义异常时返回的错误信息 这是发生异常时,统一返回的数据实体。放在common包下,每个服务公用。 创建Feign异常
Spring Cloud是基于Spring Boot的微服务框架,而Feign是一个高度集成化的、轻量级的HTTP客户端,因为能够快速简单地编写HTTP API客户端而被广泛使用。在微服务构建过程中,我们常常会遇到服务调用出现的故障或异常,而Hystrix是Netflix公司提供的一款容错框架,也是Spring Cloud的集成组件之一,主要面向分布式系统的延迟和容错,它能够提供故障和延迟特别行动,并且能够提高系统的弹性和对服务的保护。 在Spring Cloud中,我们使用Feign调用服务接口,在实现服务接口的统一hystrix降级处理方面,我们可以在Feign客户端添加@FeignClient注解,并在该注解中使用fallbackFactory属性,指定我们自定义的统一降级处理类;在该自定义类中,我们只需要实现FallbackFactory接口并实现其中的create方法即可,在该方法中实现对所有Feign客户端的统一降级处理。 总的来说,基于Feign的服务接口的统一hystrix降级处理可以为我们提供高效、可靠的服务调用保障,实现了服务降级、熔断、隔离和容错的功能,提高了系统的可靠性和健壮性。