我的编程空间,编程开发者的网络收藏夹
学习永远不晚

feign的Fallback机制

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

feign的Fallback机制

对接口使用@FeignClient后声明feign客户端后,可以使用属性fallback指定异常处理类,这个类必须实现@FeignClient作用的接口,且被注入到容器中。

@FeignClient(name = "service-provider1",fallback = NacosFeignImpl.class)public interface NacosFeignClient {    @RequestMapping(value = "/echo/{str}",method = RequestMethod.GET)    String echo(@PathVariable("str") String str);}@Componentpublic class NacosFeignImpl implements NacosFeignClient{    @Override    public String echo(String str) {        System.out.println("NacosFeignImpl#echo called");        return "echo error";    }}

添加配置项feign.hystrix.enabled=true,当配置了HystrixFeign时,即会创建HystrixFeign.Builder。

// FeignClientsConfiguration.java@Configuration@ConditionalOnClass({ HystrixCommand.class, HystrixFeign.class })protected static class HystrixFeignConfiguration {@Bean@Scope("prototype")@ConditionalOnMissingBean@ConditionalOnProperty(name = "feign.hystrix.enabled")public Feign.Builder feignHystrixBuilder() {return HystrixFeign.builder();}}

在HystrixTargeter#target()发现使用了HystrixFeign.Builder并且属性fallback存在时,就会通过targetWithFallback()创建feign客户端。这里会到容器中获取实现了@FeignClient接口的Bean。

public  T target(FeignClientFactoryBean factory, Feign.Builder feign, FeignContext context,Target.HardCodedTarget target) {if (!(feign instanceof feign.hystrix.HystrixFeign.Builder)) {return feign.target(target);}feign.hystrix.HystrixFeign.Builder builder = (feign.hystrix.HystrixFeign.Builder) feign;SetterFactory setterFactory = getOptional(factory.getName(), context,SetterFactory.class);if (setterFactory != null) {builder.setterFactory(setterFactory);}Class fallback = factory.getFallback();if (fallback != void.class) {return targetWithFallback(factory.getName(), context, target, builder, fallback);}Class fallbackFactory = factory.getFallbackFactory();if (fallbackFactory != void.class) {return targetWithFallbackFactory(factory.getName(), context, target, builder, fallbackFactory);}return feign.target(target);}

此时创建InvocationHandlerFactory,注入到属性invocationHandlerFactory,invocationHandlerFactory默认是InvocationHandlerFactory.Default,这里重写create()方法,创建了HystrixInvocationHandler的实例对象。

    Feign build(final FallbackFactory nullableFallbackFactory) {      super.invocationHandlerFactory(new InvocationHandlerFactory() {        @Override public InvocationHandler create(Target target,            Map dispatch) {          return new HystrixInvocationHandler(target, dispatch, setterFactory, nullableFallbackFactory);        }      });      super.contract(new HystrixDelegatingContract(contract));      return super.build();    }

生成代理对象时,就会调用create()对HystrixInvocationHandler实例化,这样就会调用HystrixInvocationHandler#invoke()。

  public  T newInstance(Target target) {    ......    InvocationHandler handler = factory.create(target, methodToHandler);    T proxy = (T) Proxy.newProxyInstance(target.type().getClassLoader(), new Class[]{target.type()}, handler);    for(DefaultMethodHandler defaultMethodHandler : defaultMethodHandlers) {      defaultMethodHandler.bindTo(proxy);    }    return proxy;  }

invoke()中run()的逻辑还是调用SynchronousMethodHandler#invoke()处理请求,发生异常时就会到getFallback()调用接口的实现类对象的方法。

  public Object invoke(final Object proxy, final Method method, final Object[] args)      throws Throwable {    // early exit if the invoked method is from java.lang.Object    // code is the same as ReflectiveFeign.FeignInvocationHandler    if ("equals".equals(method.getName())) {      try {        Object otherHandler =            args.length > 0 && args[0] != null ? Proxy.getInvocationHandler(args[0]) : null;        return equals(otherHandler);      } catch (IllegalArgumentException e) {        return false;      }    } else if ("hashCode".equals(method.getName())) {      return hashCode();    } else if ("toString".equals(method.getName())) {      return toString();    }    HystrixCommand hystrixCommand = new HystrixCommand(setterMethodMap.get(method)) {      @Override      protected Object run() throws Exception {        try {          return HystrixInvocationHandler.this.dispatch.get(method).invoke(args);        } catch (Exception e) {          throw e;        } catch (Throwable t) {          throw (Error) t;        }      }      @Override      protected Object getFallback() {        if (fallbackFactory == null) {          return super.getFallback();        }        try {          Object fallback = fallbackFactory.create(getExecutionException());          Object result = fallbackMethodMap.get(method).invoke(fallback, args);          if (isReturnsHystrixCommand(method)) {            return ((HystrixCommand) result).execute();          } else if (isReturnsObservable(method)) {            // Create a cold Observable            return ((Observable) result).toBlocking().first();          } else if (isReturnsSingle(method)) {            // Create a cold Observable as a Single            return ((Single) result).toObservable().toBlocking().first();          } else if (isReturnsCompletable(method)) {            ((Completable) result).await();            return null;          } else {            return result;          }        } catch (IllegalAccessException e) {          // shouldn't happen as method is public due to being an interface          throw new AssertionError(e);        } catch (InvocationTargetException e) {          // Exceptions on fallback are tossed by Hystrix          throw new AssertionError(e.getCause());        }      }    };    if (isReturnsHystrixCommand(method)) {      return hystrixCommand;    } else if (isReturnsObservable(method)) {      // Create a cold Observable      return hystrixCommand.toObservable();    } else if (isReturnsSingle(method)) {      // Create a cold Observable as a Single      return hystrixCommand.toObservable().toSingle();    } else if (isReturnsCompletable(method)) {      return hystrixCommand.toObservable().toCompletable();    }    return hystrixCommand.execute();  }                

来源地址:https://blog.csdn.net/weixin_42145727/article/details/128875925

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

feign的Fallback机制

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

feign的Fallback机制

对接口使用@FeignClient后声明feign客户端后,可以使用属性fallback指定异常处理类,这个类必须实现@FeignClient作用的接口,且被注入到容器中。 @FeignClient(name = "service-prov
2023-08-16

kafka的重试机制和ack机制是什么

Kafka的重试机制是指在消息发送过程中,如果发送失败或者出现异常,Kafka会自动尝试重新发送消息。重试机制的目的是确保消息能够成功发送到目标主题。Kafka的重试机制包括两个方面:Producer端重试:当Producer发送消息时,
2023-10-26

Android View 绘制机制的详解

View 绘制机制一、 View 树的绘图流程当 Activity 接收到焦点的时候,它会被请求绘制布局,该请求由 Android framework 处理.绘制是从根节点开始,对布局树进行 measure 和 draw。整个 View 树
2023-05-31

MySQL中的锁机制

抛砖引玉:多个查询需要在同一时刻进行数据的修改,就会产生并发控制的问题。我们需要如何避免写个问题从而保证我们的数据库数据不会被破坏。 锁的概念 读锁是共享的互相不阻塞的。多个事务在听一时刻可以同时读取同一资源,而相互不干扰。 写锁的排
2023-08-23

redis的缓存机制

redis提供了一种高效的缓存机制,使用键值对结构存储数据,并使用不同的数据结构来优化不同类型数据存储。当缓存达到容量限制时,它使用各种淘汰策略(如lru、lfu、ttl)来淘汰数据。redis缓存机制的优势包括提高应用程序性能、减少延迟、
redis的缓存机制
2024-04-19

HBase的数据版本控制机制

HBase的数据版本控制机制主要依赖于其时间戳(Timestamp)和版本号(Version Number)来实现。在HBase中,每个单元格(Cell)可以存储多个值,这些值具有不同的时间戳和版本号。时间戳表示该值被写入的时间,而版本号
HBase的数据版本控制机制
2024-10-19

Android的消息机制

一、简介 Android的消息机制主要是指Handler的运行机制,那么什么是Handler的运行机制那?通俗的来讲就是,使用Handler将子线程的Message放入主线程的Messagequeue中,在主线程使用。 二、学习内容 学习A
2022-06-06

Kafka的数据复制机制是怎样的

Kafka的数据复制机制是基于分布式发布/订阅的模式来实现的。Kafka集群中的每个主题都可以配置多个副本,每个副本都保存着完整的主题数据。当生产者发送消息到主题时,消息会被写入主题的一个分区,并且会被复制到该分区的所有副本中。这样一来,
Kafka的数据复制机制是怎样的
2024-03-11

Redis系列(四):Redis的复制机制(主从复制)

Redis的复制机制(主从复制)。 本篇博客是Redis系列的第4篇,主要讲解下Redis的主从复制机制。本系列的前3篇可以点击以下链接查看:Redis系列(一):Redis简介及环境安装Redis系列(二):Redis的5种数据结构及其常用命令
Redis系列(四):Redis的复制机制(主从复制)
2016-01-02

Redis的LRU机制介绍

在Redis中,如果设置的maxmemory,那就要配置key的回收机制参数maxmemory-policy,默认volatile-lru,参阅Redis作者的原博客:antirez weblog >> Redis as an LRU ca
2022-06-04

Java的类加载机制

很长一段时间里,我对 Java 的类加载机制都非常的抗拒,因为我觉得太难理解了。但为了成为一名优秀的 Java 工程师,我决定硬着头皮研究一下。01、字节码在聊 Java 类加载机制之前,需要先了解一下 Java 字节码,因为它和类加载机制息息相关。计算机只认
Java的类加载机制
2018-10-24

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录