iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > JAVA >feign的Fallback机制
  • 958
分享到

feign的Fallback机制

javaspringcloudfeign 2023-08-16 18:08:43 958人浏览 薄情痞子
摘要

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

对接口使用@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

--结束END--

本文标题: feign的Fallback机制

本文链接: https://www.lsjlt.com/news/371897.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

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

下载Word文档
猜你喜欢
  • feign的Fallback机制
    对接口使用@FeignClient后声明feign客户端后,可以使用属性fallback指定异常处理类,这个类必须实现@FeignClient作用的接口,且被注入到容器中。 @FeignClient(name = "service-prov...
    99+
    2023-08-16
    java spring cloud feign
  • springcloud之Feign、ribbon如何设置超时时间和重试机制
    Feign、ribbon设置超时时间和重试机制 前言 我们在微服务调用服务的时候,会使用feign和ribbon,比如有一个实例发生了故障而该情况还没有被服务治理机制及时的发现和摘除...
    99+
    2024-04-02
  • Spring Cloud Gateway Hystrix fallback获取异常信息的处理
    Gateway Hystrix fallback获取异常信息 gateway fallback后,需要知道请求的是哪个接口以及具体的异常信息,根据不同的请求以及异常进行不同的处理。一...
    99+
    2024-04-02
  • 关于Feign的覆写默认配置和Feign的日志
    目录Feign的覆写默认配置Feign Logging 日志Feign进行日志配置Feign有四种类型的日志列出两种在项目中配置Feign日志的方法Feign的覆写默认配置 A ce...
    99+
    2024-04-02
  • SpringCloud Feign的使用简介
    目录简介使用总结简介 feign是声明式的web service客户端,它让微服务之间的调用变得更简单了,类似controller调用service。Spring Cloud集成了...
    99+
    2024-04-02
  • 怎么使用原生的Feign
    这篇文章主要介绍了怎么使用原生的Feign,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。什么是FeignFeign 是由 Netflix 团队开发的一款基于 Java 实现的...
    99+
    2023-06-25
  • 详解Feign的实现原理
    目录一、什么是Feign二、为什么用Feign三、实例3.1、原生使用方式3.2、结合 Spring Cloud 使用方式四、探索Feign五、总结一、什么是Feign Feign ...
    99+
    2024-04-02
  • springcloud feign的用法是什么
    Feign是一个声明式的Web Service客户端,它使得编写Web服务客户端变得更加简单。使用Feign,只需要创建一个接口并使...
    99+
    2023-10-20
    springcloud feign
  • 浅谈Android IPC机制之Binder的工作机制
    目录进程和线程的关系跨进程的种类Serializable,Parcelable接口Binder进程和线程的关系 按照操作系统中的描述,线程是CPU调度的最小单位,同时线程也是一种有限...
    99+
    2024-04-02
  • kafka的重试机制和ack机制是什么
    Kafka的重试机制是指在消息发送过程中,如果发送失败或者出现异常,Kafka会自动尝试重新发送消息。重试机制的目的是确保消息能够成...
    99+
    2023-10-26
    kafka
  • Android View 绘制机制的详解
    View 绘制机制一、 View 树的绘图流程当 Activity 接收到焦点的时候,它会被请求绘制布局,该请求由 Android framework 处理.绘制是从根节点开始,对布局树进行 measure 和 draw。整个 View 树...
    99+
    2023-05-31
    android view 绘制
  • 浅谈Ribbon、Feign和OpenFeign的区别
    Ribbon Ribbon 是 Netflix开源的基于HTTP和TCP等协议负载均衡组件 Ribbon 可以用来做客户端负载均衡,调用注册中心的服务 Ribbon的使用需要代码里手...
    99+
    2024-04-02
  • redis的缓存机制
    redis提供了一种高效的缓存机制,使用键值对结构存储数据,并使用不同的数据结构来优化不同类型数据存储。当缓存达到容量限制时,它使用各种淘汰策略(如lru、lfu、ttl)来淘汰数据。r...
    99+
    2024-04-19
    redis 键值对
  • MySQL中的锁机制
    抛砖引玉:多个查询需要在同一时刻进行数据的修改,就会产生并发控制的问题。我们需要如何避免写个问题从而保证我们的数据库数据不会被破坏。 锁的概念 读锁是共享的互相不阻塞的。多个事务在听一时刻可以同时读取同一资源,而相互不干扰。 写锁的排...
    99+
    2023-08-23
    mysql 数据库
  • TCP的重传机制
            我们都知道基于TCP协议的传输都是相对稳定和安全的,那么它是通过何种方法保证数据的正确性以及安全性呢,其中之一就是因为TCP具有重传机制。由于TCP是基于双方连接的,因此需要接收端和发送端保证连接之后才会发送有效信息,所...
    99+
    2023-09-22
    tcp/ip 服务器 网络
  • HashMap的扩容机制
    目录 一、HashMap的底层 二、HashMap的扩容机制原理 1、JDK1.7版本扩容 2、JDK1.8版本扩容 三、HashMap底层JDK1.7到JDK1.8的变化 一、HashMap的底层 底层:采用数组+链表(JDK1.7)...
    99+
    2023-09-04
    java 面试 数据结构 链表 容器
  • mysql myisam的锁机制
    首先我们知道MySQL支持多种引擎,并且不同存储引擎有很多不同,最重要的 ...
    99+
    2024-04-02
  • spring cloud Feign使用@RequestLine遇到的坑
    Feign使用@RequestLine遇到的坑 如何在微服务项目中调用其它项目的接口试使用spring cloud feign声明式调用。 @FeignClient(name=...
    99+
    2024-04-02
  • springcloud之Feign超时问题的解决
    问题背景 最近公司项目有个功能需进行三层Feign调用,且还要调外部接口,延迟挺大,造成Feign一直提示Read timed out executing POST。 feign...
    99+
    2024-04-02
  • Kafka的数据复制机制是怎样的
    Kafka的数据复制机制是基于分布式发布/订阅的模式来实现的。Kafka集群中的每个主题都可以配置多个副本,每个副本都保存着完整的主...
    99+
    2024-03-11
    Kafka
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作