精华内容
下载资源
问答
  • 2022-02-22 16:56:53

    如果是简单参数,用@RequestParam或者@PathVariable注解

    如果是对象参数,用@RequestBody注解

    更多相关内容
  • Feign远程调用

    2022-04-03 09:10:04
    2.Feign远程调用 先来看我们以前利用RestTemplate发起远程调用的代码: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aETQpudi-1648948200523)(assets/image-20210714174814204.png)] ...

    2.Feign远程调用

    先来看我们以前利用RestTemplate发起远程调用的代码:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aETQpudi-1648948200523)(assets/image-20210714174814204.png)]

    存在下面的问题:

    •代码可读性差,编程体验不统一

    •参数复杂URL难以维护

    Feign是一个声明式的http客户端,官方地址:https://github.com/OpenFeign/feign

    其作用就是帮助我们优雅的实现http请求的发送,解决上面提到的问题。

    2.1.Feign替代RestTemplate

    Fegin的使用步骤如下:

    1)引入依赖

    我们在order-service服务的pom文件中引入feign的依赖:

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    

    2)添加注解

    在order-service的启动类添加注解开启Feign的功能:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wxaIrwGF-1648948200524)(assets/image-20210714175102524.png)]

    3)编写Feign的客户端

    在order-service中新建一个接口,内容如下:

    package cn.itcast.order.client;
    
    import cn.itcast.order.pojo.User;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    
    @FeignClient("userservice")
    public interface UserClient {
        @GetMapping("/user/{id}")
        User findById(@PathVariable("id") Long id);
    }
    

    这个客户端主要是基于SpringMVC的注解来声明远程调用的信息,比如:

    • 服务名称:userservice
    • 请求方式:GET
    • 请求路径:/user/{id}
    • 请求参数:Long id
    • 返回值类型:User

    这样,Feign就可以帮助我们发送http请求,无需自己使用RestTemplate来发送了。

    4)测试

    修改order-service中的OrderService类中的queryOrderById方法,使用Feign客户端代替RestTemplate:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X1tqZgQ4-1648948200525)(assets/image-20210714175415087.png)]

    是不是看起来优雅多了。

    5)总结

    使用Feign的步骤:

    ① 引入依赖

    ② 添加@EnableFeignClients注解

    ③ 编写FeignClient接口

    ④ 使用FeignClient中定义的方法代替RestTemplate

    2.2.自定义配置

    Feign可以支持很多的自定义配置,如下表所示:

    类型作用说明
    feign.Logger.Level修改日志级别包含四种不同的级别:NONE、BASIC、HEADERS、FULL
    feign.codec.Decoder响应结果的解析器http远程调用的结果做解析,例如解析json字符串为java对象
    feign.codec.Encoder请求参数编码将请求参数编码,便于通过http请求发送
    feign. Contract支持的注解格式默认是SpringMVC的注解
    feign. Retryer失败重试机制请求失败的重试机制,默认是没有,不过会使用Ribbon的重试

    一般情况下,默认值就能满足我们使用,如果要自定义时,只需要创建自定义的@Bean覆盖默认Bean即可。

    下面以日志为例来演示如何自定义配置。

    2.2.1.配置文件方式

    基于配置文件修改feign的日志级别可以针对单个服务:

    feign:  
      client:
        config: 
          userservice: # 针对某个微服务的配置
            loggerLevel: FULL #  日志级别 
    

    也可以针对所有服务:

    feign:  
      client:
        config: 
          default: # 这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置
            loggerLevel: FULL #  日志级别 
    

    而日志的级别分为四种:

    • NONE:不记录任何日志信息,这是默认值。
    • BASIC:仅记录请求的方法,URL以及响应状态码和执行时间
    • HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息
    • FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据。

    2.2.2.Java代码方式

    也可以基于Java代码来修改日志级别,先声明一个类,然后声明一个Logger.Level的对象:

    public class DefaultFeignConfiguration  {
        @Bean
        public Logger.Level feignLogLevel(){
            return Logger.Level.BASIC; // 日志级别为BASIC
        }
    }
    

    如果要全局生效,将其放到启动类的@EnableFeignClients这个注解中:

    @EnableFeignClients(defaultConfiguration = DefaultFeignConfiguration .class) 
    

    如果是局部生效,则把它放到对应的@FeignClient这个注解中:

    @FeignClient(value = "userservice", configuration = DefaultFeignConfiguration .class) 
    

    2.3.Feign使用优化

    Feign底层发起http请求,依赖于其它的框架。其底层客户端实现包括:

    •URLConnection:默认实现,不支持连接池

    •Apache HttpClient :支持连接池

    •OKHttp:支持连接池

    因此提高Feign的性能主要手段就是使用连接池代替默认的URLConnection。

    这里我们用Apache的HttpClient来演示。

    1)引入依赖

    在order-service的pom文件中引入Apache的HttpClient依赖:

    <!--httpClient的依赖 -->
    <dependency>
        <groupId>io.github.openfeign</groupId>
        <artifactId>feign-httpclient</artifactId>
    </dependency>
    

    2)配置连接池

    在order-service的application.yml中添加配置:

    feign:
      client:
        config:
          default: # default全局的配置
            loggerLevel: BASIC # 日志级别,BASIC就是基本的请求和响应信息
      httpclient:
        enabled: true # 开启feign对HttpClient的支持
        max-connections: 200 # 最大的连接数
        max-connections-per-route: 50 # 每个路径的最大连接数
    

    接下来,在FeignClientFactoryBean中的loadBalance方法中打断点:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ponOXRaB-1648948200526)(assets/image-20210714185925910.png)]

    Debug方式启动order-service服务,可以看到这里的client,底层就是Apache HttpClient:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V8wTv4yh-1648948200526)(assets/image-20210714190041542.png)]

    总结,Feign的优化:

    1.日志级别尽量用basic

    2.使用HttpClient或OKHttp代替URLConnection

    ① 引入feign-httpClient依赖

    ② 配置文件开启httpClient功能,设置连接池参数

    2.4.最佳实践

    所谓最佳实践,就是使用过程中总结的经验,最好的一种使用方式。

    自习观察可以发现,Feign的客户端与服务提供者的controller代码非常相似:

    feign客户端:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pXge7mTu-1648948200526)(assets/image-20210714190542730.png)]

    UserController:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YaG4vifV-1648948200527)(assets/image-20210714190528450.png)]

    有没有一种办法简化这种重复的代码编写呢?

    2.4.1.继承方式

    一样的代码可以通过继承来共享:

    1)定义一个API接口,利用定义方法,并基于SpringMVC注解做声明。

    2)Feign客户端和Controller都集成改接口

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KKEocVU7-1648948200527)(assets/image-20210714190640857.png)]

    优点:

    • 简单
    • 实现了代码共享

    缺点:

    • 服务提供方、服务消费方紧耦合

    • 参数列表中的注解映射并不会继承,因此Controller中必须再次声明方法、参数列表、注解

    2.4.2.抽取方式

    将Feign的Client抽取为独立模块,并且把接口有关的POJO、默认的Feign配置都放到这个模块中,提供给所有消费者使用。

    例如,将UserClient、User、Feign的默认配置都抽取到一个feign-api包中,所有微服务引用该依赖包,即可直接使用。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0IEjjSfv-1648948200527)(assets/image-20210714214041796.png)]

    2.4.3.实现基于抽取的最佳实践

    1)抽取

    首先创建一个module,命名为feign-api:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M2tSkxl3-1648948200528)(assets/image-20210714204557771.png)]

    项目结构:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Us2Z5XN9-1648948200531)(assets/image-20210714204656214.png)]

    在feign-api中然后引入feign的starter依赖

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    

    然后,order-service中编写的UserClient、User、DefaultFeignConfiguration都复制到feign-api项目中

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IUwIPuIO-1648948200531)(assets/image-20210714205221970.png)]

    2)在order-service中使用feign-api

    首先,删除order-service中的UserClient、User、DefaultFeignConfiguration等类或接口。

    在order-service的pom文件中中引入feign-api的依赖:

    <dependency>
        <groupId>cn.itcast.demo</groupId>
        <artifactId>feign-api</artifactId>
        <version>1.0</version>
    </dependency>
    

    修改order-service中的所有与上述三个组件有关的导包部分,改成导入feign-api中的包

    3)重启测试

    重启后,发现服务报错了:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NbHcWkqF-1648948200531)(assets/image-20210714205623048.png)]

    这是因为UserClient现在在cn.itcast.feign.clients包下,

    而order-service的@EnableFeignClients注解是在cn.itcast.order包下,不在同一个包,无法扫描到UserClient。

    4)解决扫描包问题

    方式一:

    指定Feign应该扫描的包:

    @EnableFeignClients(basePackages = "cn.itcast.feign.clients")
    

    方式二:

    指定需要加载的Client接口:

    @EnableFeignClients(clients = {UserClient.class})
    
    展开全文
  • 主要介绍了使用Spring Cloud Feign远程调用的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • Feign远程调用的执行流程 由于Feign中生成RPC接口JDK动态代理实例涉及的InvocationHandler调用处理器有多种,导致Feign远程调用的执行流程稍微有所区别,但是远程调用执行流程的主要步骤是一致的。这里主要介绍与两...

    Feign远程调用的执行流程

    由于Feign中生成RPC接口JDK动态代理实例涉及的InvocationHandler调用处理器有多种,导致Feign远程调用的执行流程稍微有所区别,但是远程调用执行流程的主要步骤是一致的。这里主要介绍与两类InvocationHandler调用处理器相关的RPC执行流程:

    (1)与默认的调用处理器FeignInvocationHandler相关的RPC执行流程。

    (2)与Hystrix调用处理器HystrixInvocationHandler相关的RPC执行流程。

    还是以uaa-provider启动过程中的DemoClient接口的动态代理实例的执行过程为例演示和分析远程调用的执行流程。

    与FeignInvocationHandler相关的远程调用执行流程

    FeignInvocationHandler是默认的调用处理器,如果进行特殊的配置,那么Feign将默认使用此调用处理器。

    结合uaa-provider服务中DemoClient的动态代理实例的hello()方法远程调用执行过程,这里详细介绍与FeignInvocationHandler相关的远程调用执行流程,如图3-25所示。

    图3-25 与FeignInvocationHandler相关的远程调用执行流程

    整体的远程调用执行流程大致分为4步,具体如下:

    (1)通过Spring IOC容器实例完成动态代理实例的装配。

    前文讲到,Feign在启动时会为加上了@FeignClient注解的所有远程接口(包括DemoClient接口)创建一个FactoryBean工厂实例,并注册到Spring IOC容器。然后在uaa-provider的DemoRPCController控制层类中,通过@Resource注解从Spring IOC容器找到FactoryBean工厂实例,通过其getObject()方法获取到动态代理实例,装配给DemoRPCController实例的成员变量demoClient。

    在需要进行hello()远程调用时,直接通过demoClient成员变量调用JDK动态代理实例的hello()方法。

    (2)执行InvocationHandler调用处理器的invoke(...)方法。

    前面讲到,JDK动态代理实例的方法调用过程是通过委托给InvocationHandler调用处理器完成的,故在调用demoClient的hello()方法时,会调用到它的调用处理器FeignInvocationHandler实例的invoke(...)方法。

    大家知道,FeignInvocationHandler实例内部保持了一个远程调用方法反射实例和方法处理器的dispatch映射。FeignInvocationHandle在它的invoke(...)方法中会根据hello()方法的Java反射实例在dispatch映射对象中找到对应的MethodHandler方法处理器,然后由后者完成实际的HTTP请求和结果的处理。

    (3)执行MethodHandler方法处理器的invoke(...)方法。

    通过前面关于MethodHandler方法处理器的组件介绍,大家都知道,feign默认的方法处理器为SynchronousMethodHandler同步调用处理器,它的invoke(...)方法主要通过内部feign。Client类型的client成员实例完成远程URL请求执行和获取远程结果。

    feign.Client客户端有多种类型,不同的类型完成URL请求处理的具体方式不同。(4)通过feign.Client客户端成员完成远程URL请求执行和获取远程结果。

    如果MethodHandler方法处理器client成员实例是默认的feign.Client.Default实现类,就通过JDK自带的HttpURLConnnection类完成远程URL请求执行和获取远程结果。

    如果MethodHandler方法处理器实例的client客户端是ApacheHttpClient客户端实现类,就使用ApacheHttpClient开源组件完成远程URL请求执行和获取远程结果。

    如果MethodHandler方法处理器实例的client客户端是LoadBalancerFeignClient负载均衡客户端实现类,就使用Ribbon结算出最佳的Provider节点,然后由内部的delegate委托客户端成员去请求Provider服务,完成URL请求处理。

    以上4步基本上就是Spring Cloud中的Feign远程调用的执行流程。

    然而,默认的基于FeignInvocationHandler调用处理器的执行流程在运行机制和调用性能上都满足不了生产环境的要求,大致原因有以下两点:

    (1)在远程调用过程中没有异常的熔断监测和恢复机制。

    (2)没有用到高性能的HTTP连接池技术。

    接下来将为大家介绍一种结合Hystrix进行RPC保护的远程调用处理流程。在该流程中所使用的InvocationHandler调用处理器叫作HystrixInvocationHandler调用处理器。

    这里作为铺垫,首先为大家介绍HystrixInvocationHandler调用处理器本身的具体实现。

     与HystrixInvocationHandler相关的远程调用执行流程

    HystrixInvocationHandler调用处理器类位于feign.hystrix包中,其字节码文件不是处于feign核心包feign-core-*.jar中,而是在扩展包feignhystrix-*.jar中。这里的*表示的是与Spring Cloud版本配套的版本号,当Spring Cloud的版本为Finchley.RELEASE时,feign-core和feign-hystrix两个JAR包的版本号都为9.5.1。

    HystrixInvocationHandler是具备RPC保护能力的调用处理器,它实现了InvocationHandler接口,对接口的invoke(...)抽象方法的实现如下:

    package feign.hystrix;
    //省略import
    final class HystrixInvocationHandler implements InvocationHandler {
    ...
    //... Map映射:Key为RPC方法的反射实例,value为方法处理器
    private final Map<Method, MethodHandler> dispatch;
    ...
    public Object invoke(Object proxy, final Method method, final Object[] args) throws Throwable {
     //创建一个HystrixCommand命令,对同步方法调用器进行封装
     HystrixCommand<Object> hystrixCommand =
     new HystrixCommand<Object>
     ( (Setter)this.setterMethodMap.get(method) )
    {
     protected Object run() throws Exception {
     try {
    SynchronousMethodHandler handler=HystrixInvocationHandler.this.dispatch.get(method);
     return handler.invoke(args);
     } catch (Exception var2) {
     throw var2;
     } catch (Throwable var3) {
     throw (Error)var3;
     }
     }
     protected Object getFallback() {
     //省略HystrixCommand的异常回调
     }
     };
     //根据method的返回值类型,或返回hystrixCommand,或直接执行
     if (this.isReturnsHystrixCommand(method)) {
     return hystrixCommand;
     } else if (this.isReturnsObservable(method)) {
     return hystrixCommand.toObservable();
     } else if (this.isReturnsSingle(method)) {
     return hystrixCommand.toObservable().toSingle();
     } else {
     //直接执行
     return this.isReturnsCompletable(method) ?
     hystrixCommand.toObservable().toCompletable() : hystrixCommand.execute();
     }
     ...
    }

    HystrixInvocationHandler调用处理器与默认调用处理器FeignInvocationHandler有一个共同点:都有一个非常重要的Map类型成员dispatch映射,保存着RPC方法反射实例到MethodHandler方法处理器的映射。

    在源码中,HystrixInvocationHandler的invoke(...)方法会创建hystrixCommand命令实例,对从dispatch获取的SynchronousMethodHandler实例进行封装,然后对RPC方法实例method进行判断,判断是直接返回hystrixCommand命令实例,还是立即执行其execute()方法。默认情况下,都是立即执行它的execute()方法。

    HystrixCommand具备熔断、隔离、回退等能力,如果它的run()方法执行发生异常,就会执行getFallback()失败回调方法,这一点后面会详细介绍。

    回到uaa-provider服务中DemoClient动态代理实例的hello()方法的具体执行过程,在执行命令处理器hystrixCommand实例的run()方法时,步骤如下:

    (1)根据RPC方法DemoClient.hello()的反射实例在dispatch映射对象中找到对应的方法处理器MethodHandler实例。

    (2)调用MethodHandler方法处理器的invoke(...)方法完成实际的hello()方法所配置的远程URL的HTTP请求和结果的处理。

    如果MethodHandler内的RPC调用出现异常,比如远程server宕机、网络延迟太大而导致请求超时、远程server来不及响应等,hystrixCommand命令器就会调用失败回调方法getFallback()返回回退结果。

    而hystrixCommand的getFallback()方法最终会调用配置在RPC接口@FeignClient注解的fallback属性上的失败回退类中对应的回退方法,执行业务级别的失败回退处理。

    使用HystrixInvocationHandler方法处理器进行远程调用,总体流程与使用默认的方法处理器FeignInvocationHandler进行远程调用大致是相同的。

    以uaa-provider模块的DemoClient中hello()方法的远程调用执行过程为例,进行整体流程的展示,具体的时序图如图3-26所示。

    图3-26 与HystrixInvocationHandler相关的远程调用执行流程

    总体来说,使用HystrixInvocationHandler处理器的执行流程与使用FeignInvocationHandler默认的调用处理器相比大致是相同的。不同的是,HystrixInvocationHandler增加了RPC的保护机制。

    Feign远程调用的完整流程及其特性

    Feign是一个声明式的RPC调用组件,它整合了Ribbon和Hystrix,使得服务调用更加简单。Feign提供了HTTP请求的模板,通过编写简单的接口和方法注解就可以定义好HTTP请求的参数、格式、地址等信息。

    Feign极大地简化了RPC远程调用,大家只需要像调用普通方法一样就可以完成RPC远程调用。

    Feign远程调用的核心是通过一系列封装和处理,将以JAVA注解方式定义的RPC方法最终转换成HTTP请求,然后将HTTP请求的响应结果解码成POJO对象返回给调用者。

    Feign远程调用的完整流程如图3-27所示。

    图3-27 Feign远程调用的完整流程

    从图3-27可以看到,Feign通过对RPC注解的解析将请求模板化。当实际调用时传入参数,再根据参数应用到请求模板上,进而转化成真正的Request请求。通过Feign及其动态代理机制,Java开发人员不用再通过HTTP框架封装HTTP请求报文的方式完成远程服务的HTTP调用。

    Spring Cloud Feign具有如下特性:

    (1)可插拔的注解支持,包括Feign注解和Spring MVC注解。

    (2)支持可插拔的HTTP编码器和解码器。

    (3)支持Hystrix和它的RPC保护机制。

    (4)支持Ribbon的负载均衡。

    (5)支持HTTP请求和响应的压缩。

    总体来说,使用Spring Cloud Feign组件本身整合了Ribbon和Hystrix,可设计一套稳定可靠的弹性客户端调用方案,避免整个系统出现雪崩效应。

    本文给大家讲解的内容是SpringCloudRPC远程调用核心原理:Feign远程调用的执行流程

    1. 下篇文章给大家讲解的是SpringCloudRPC远程调用核心原理:HystrixFeign动态代理实例的创建流程;
    2. 觉得文章不错的朋友可以转发此文关注小编;
    3. 感谢大家的支持!
    展开全文
  • Feign 远程调用

    2022-04-20 09:50:24
    先来看我们以前利用RestTemplate发起远程调用的代码: 存在下面的问题: •代码可读性差,编程体验不统一。 •参数复杂URL难以维护。 Feign是一个声明式的http客户端,其作用就是帮助我们优雅的实现http请求的发送,...

    【学习目录】
    Feign替换RestTemplate
    自定义配置
    Feign使用优化
    Feign最佳实践

    Feign替换RestTemplate

    官方地址:https://github.com/OpenFeign/feign
    先来看我们以前利用RestTemplate发起远程调用的代码:在这里插入图片描述

    存在下面的问题:
    •代码可读性差,编程体验不统一。
    •参数复杂URL难以维护。
    Feign是一个声明式的http客户端,其作用就是帮助我们优雅的实现http请求的发送,解决上面提到的问题。

    如何使用Feign代替RestTemplate?
    (1)引入依赖
    我们在order-service服务的pom文件中引入feign的依赖。

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    

    (2)添加注解
    在order-service的启动类上添加@EnableFeignClients注解。

    (3)编写Feign的客户端
    创建一个接口, 添加@FeignClient注解, 这里userservice和要访问的 服务对应, 返回值和参数要和获取的controller对应

    @FeignClient("userservice")
    public interface UserClient {
        @GetMapping("/user/{id}")
        User findById(@PathVariable Long id);
    }
    

    这个客户端主要是基于SpringMVC的注解来声明远程调用的信息,比如:

    • 服务名称:userservice
    • 请求方式:GET
    • 请求路径:/user/{id}
    • 请求参数:Long id
    • 返回值类型:User

    (4)测试

    修改order-service中的OrderService类中的queryOrderById方法,使用Feign客户端代替RestTemplate:
    在这里插入图片描述

    自定义配置

    Feign可以支持很多的自定义配置,如下表所示:

    类型作用说明
    feign.Logger.Level修改日志级别包含四种不同的级别:NONE、BASIC、HEADERS、FULL
    feign.codec.Decoder响应结果的解析器http远程调用的结果做解析,例如解析json字符串为java对象
    feign.codec.Encoder请求参数编码将请求参数编码,便于通过http请求发送
    feign. Contract支持的注解格式默认是SpringMVC的注解
    feign. Retryer失败重试机制请求失败的重试机制,默认是没有,不过会使用Ribbon的重试

    一般情况下,默认值就能满足我们使用,如果要自定义时,只需要创建自定义的@Bean覆盖默认Bean即可。

    【如何自定义配置】

    (1)配置文件方式
    基于配置文件修改feign的日志级别可以针对单个服务。

    feign:  
      client:
        config: 
          userservice: # 针对某个微服务的配置
            loggerLevel: FULL #  日志级别 
    

    也可以针对所有服务:

    feign:  
      client:
        config: 
          default: # 这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置
            loggerLevel: FULL #  日志级别 
    

    而日志的级别分为四种:

    • NONE:不记录任何日志信息,这是默认值。
    • BASIC:仅记录请求的方法,URL以及响应状态码和执行时间
    • HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息
    • FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据。

    (2)代码方式
    也可以基于Java代码来修改日志级别,先声明一个类,然后声明一个Logger.Level的对象。

    public class DefaultFeignConfiguration  {
        @Bean
        public Logger.Level feignLogLevel(){
            return Logger.Level.BASIC; // 日志级别为BASIC
        }
    }
    

    如果要【全局生效】,将其放到启动类的@EnableFeignClients这个注解中:

    @EnableFeignClients(defaultConfiguration = DefaultFeignConfiguration .class) 
    

    如果是【局部生效】,则把它放到对应的@FeignClient这个注解中:

    @FeignClient(value = "userservice", configuration = DefaultFeignConfiguration .class) 
    

    Feign使用优化

    Feign底层发起http请求,依赖于其它的框架。其底层客户端实现包括:

    • URLConnection:默认实现,不支持连接池。
    • Apache HttpClient :支持连接池。
    • OKHttp:支持连接池。

    因此提高Feign的性能主要手段就是使用【连接池】代替默认的URLConnection。
    这里我们用Apache的HttpClient来演示。
    (1)引入依赖
    在order-service的pom文件中引入Apache的HttpClient依赖。

    <!--httpClient的依赖 -->
    <dependency>
        <groupId>io.github.openfeign</groupId>
        <artifactId>feign-httpclient</artifactId>
    </dependency>
    

    (2)配置连接池
    在order-service的application.yml中添加配置。

    feign:
      client:
        config:
          default: # default全局的配置
            loggerLevel: BASIC # 日志级别,BASIC就是基本的请求和响应信息
      httpclient:
        enabled: true # 开启feign对HttpClient的支持
        max-connections: 200 # 最大的连接数
        max-connections-per-route: 50 # 每个路径的最大连接数
    

    接下来,在FeignClientFactoryBean中的loadBalance方法中打断点:
    在这里插入图片描述
    Debug方式启动order-service服务,可以看到这里的client,底层就是Apache HttpClient:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GgzDGUHq-1650419402746)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20220414171900715.png)]

    总结
    Feign的优化:
    1.日志级别尽量用basic。
    2.使用HttpClient或OKHttp代替URLConnection。
    配置底层实现的步骤:
    (1)引入feign-httpClient依赖。
    (2)配置文件开启httpClient功能,设置连接池参数。

    Feign最佳实践

    所谓最近实践,就是使用过程中总结的经验,最好的一种使用方式。观察可以发现,Feign的客户端与服务提供者的controller代码非常相似:

    feign客户端:
    在这里插入图片描述
    UserController:
    在这里插入图片描述

    有没有一种办法简化这种重复的代码编写呢?

    方式1: 继承

    一样的代码可以通过继承来共享:
    1)定义一个API接口,利用定义方法,并基于SpringMVC注解做声明。
    2)Feign客户端和Controller都集成改接口。
    在这里插入图片描述

    优点:

    • 简单
    • 实现了代码共享

    缺点:

    • 服务提供方、服务消费方紧耦合
    • 参数列表中的注解映射并不会继承,因此Controller中必须再次声明方法、参数列表、注解

    方式2:抽取

    将Feign的Client抽取为独立模块,并且把接口有关的POJO、默认的Feign配置都放到这个模块中,提供给所有消费者使用。
    例如,将UserClient、User、Feign的默认配置都抽取到一个feign-api包中,所有微服务引用该依赖包,即可直接使用。

    在这里插入图片描述
    (1)结构抽取
    首先创建一个module,命名为feign-api
    (2)在feign-api中然后引入feign的starter依赖

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    

    然后,order-service中编写的UserClient、User、DefaultFeignConfiguration都复制到feign-api项目中
    (3)使用feign-api
    在order-service中使用feign-api, 首先,删除order-service中的UserClient、User、DefaultFeignConfiguration等类或接口。
    在order-service的pom文件中中引入feign-api的依赖:

    <dependency>
        <groupId>cn.itcast.demo</groupId>
        <artifactId>feign-api</artifactId>
        <version>1.0</version>
    </dependency>
    

    修改order-service中的所有与上述三个组件有关的导包部分,改成导入feign-api中的包。

    (4)重启测试

    展开全文
  • 当我们要使用feign远程调用其他项目的接口时,要在启动类上注解@EnableFeignClients 然后将创建一个接口要,将要调用的接口的注解和返回值类型、函数名那两行粘过去。这里,要尤其注意,粘过去之后,如果函数里有...
  • 今天使用Feign进行远程调用时出现一个异常 feign.codec.DecodeException 报错原因:返回值对象中没有无参构造 解决方法: 在对象中添加无参构造
  • 一、Feign来实现远程调用 1、添加Feign的配置 2、在启动类开启该功能 3、创建client接口,如下: 4、服务层装配后使用如下 5、小结 二、Feign的自定义配置 1、基于yml的配置 2、基于java代码的配置 3、小结...
  • 文章目录SpringCloud之Feign 远程调用一、RestTemplate远程调用二、Feign远程调用1.引入库2.添加注解二、Feign远程调用1.写要远程调用接口的方法2.Controller三、Feign自定义配置三、Feign性能优化 一、...
  • 今天写代码的时候发现通过feign远程调用的话,默认是不带我们浏览器的请求头的,这就造成了我们使用session的一些问题。 接下来我们就一起来看看问题原因和解决方法吧。 问题重现 我们发现,在template中的headers中...
  • Feign远程调用 先来看以前利用RestTemplate发起远程调用的代码: 存在下面的问题: •代码可读性差,编程体验不统一 •参数复杂URL难以维护 Feign是一个声明式的http客户端,官方地址:...
  • 今天在写业务的时候,需要通过feign调用远程接口,平常只是调用就行了,没有了解到他是如何代码实现的,今天就使用debug来解开feign为什么可以远程调用的面纱。 希望看本文章的同学朋友们,可以自己写一个简单的远程...
  • Feign远程调用服务时返回Null的情况 用object接收也是空的情况下,可以考虑请求头的Content-Type是否正确和请求体是否加了相应的注解,如@requestbody@requestparam@requestHeaders@requestpart
  • feign远程调用接口

    2021-04-15 14:08:29
    标题 feign远程调用接口 问题描述: 远程调用接口,类配置,接口实现,调用方法时结果执行,返回值报错。 package gds.bigdata.iltmonitor.feignclient; import java.util.List; import java.util.Map; import org...
  • 问题:feign远程调用时,会构造很多拦截器(RequestInterceptor interceptor : requestInterceptors),并且在进行请求时,会创建一个新的请求模板,并且这个新的请求没有任何请求头,这样就会导致信息丢失。...
  • Feign 远程调用、Ribbin 负载均衡和重试
  • 项目中开发中,经常会用到调用其他项目的接口 或者第三方接口的情况,以前经常使用的是spring 的restTemplate 或者...一,是什么feign 是Netflix 开发的声明式的http客户端,可以帮我们更加方便的调用http接口。在使...
  • Feign 远程调用丢失请求头问题。 Feign 异步调用情况下,丢失请求上下文问题。
  • Feign远程调用.md

    2021-09-28 14:33:39
    Feign远程调用.md
  • springcloud微服务(六)—— 基于feign远程调用 前面我们远程调是通过直接输入url方式来实现的,这样写不利于维护,也不够优雅。本节使用feign能够优雅的实现远程调用。 1.引入依赖 <!-- feign客户端依赖-->...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 17,570
精华内容 7,028
关键字:

feign远程调用

友情链接: myshop.rar