目录

1.1Feign优势

2.spring cloud alibaba整合Feign

3.Spring Cloud Feign日志配置

4.Feign契约配置

5.Feign超时时间配置

6.Open Feign自定义拦截器

7.Feign远程调用原理


1.什么是Feign

Feign是Netflix开发的声明式、模板化的HTTP客户端,Feign支持多种注解,例如JAX-RS注解。

spring cloud openfeign对feign进行了增强,使其支持spring mvc注解,另外还整合了Ribbon和Nacos,从而使得feign的使用更加方便。

1.1Feign优势

Feign可以做到使用http请求远程服务时就像调用本地方法一样的体验,开发者完全感知不到这是远程调用,更感知不到这是http请求。它像dubbo一样,consumer直接调用接口调用provider,而不需要通过常规的Http client构造请求再解析返回数据。它解决了让开发者调用远程接口跟调用本地方法一样,无需关注与远程的交互细节,更无需关注分布式环境开发。

2.spring cloud alibaba整合Feign

(1)pom.xml中引入依赖

       <!-- 添加springcloud 的openfeign--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><!-- 排除冲突的jar包文件--><exclusions><exclusion><groupId>org.springframework</groupId><artifactId>spring-web</artifactId></exclusion><exclusion><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-commons</artifactId></exclusion></exclusions></dependency>

(2)application.properties中配置链接nacos的信息

server.port=8084
#应用名称,nacos会将该名称当做服务名称
spring.application.name=order-service
#nacos服务连接地址
spring.cloud.nacos.server-addr=127.0.0.1:8848
#nacos discovery连接用户名
spring.cloud.nacos.discovery.username=nacos
#nacos discovery连接密码
spring.cloud.nacos.discovery.password=nacos
#nacos discovery工作空间
spring.cloud.nacos.discovery.workspace=public

(3)编写Feign调用接口

使用@FeignClient来定义feign的调用方式,value为调用的服务名,path对应被调用服务处理的controller层,按相同的写法把提供者的方法在此接口中实现,使用spring mvc注解请求的方式定义。
/*** 使用@FeignClient来定义feign的调用方式,value为调用的服务名,path对应被调用服务处理的controller层*/
@FeignClient(value = "stock-service",path ="/stock" )
public interface StockOpenFeign {@RequestMapping("/reduct")String reduct();
}/*** @RequestMapping("/stock")* public class StockController {**     @Value("${server.port}")*     String port;**     @RequestMapping("/reduct")*     public String reduct(){*         System.out.println("扣减库存");*         return "扣减库存成功,端口号为:"+port+"的服务提供调用";*     }* }*/

(4)调用类在启动类代码中添加@EnableFeignClients注解

/*** 程序启动类*/
@SpringBootApplication
@EnableFeignClients
public class OrderApplication {public static void main(String[] args) {SpringApplication.run(OrderApplication.class,args);}
}

(5)像调用本地一样发起远程调用,使用接口调用

之前使用spring boot 的RestTemplate调用方式:

①先创建RestTemplate

    //程序启动时创建RestTemplate//使用注解LoadBalanced标识负载均衡,默认轮询的方式@Bean@LoadBalancedpublic RestTemplate restTemplate(RestTemplateBuilder builder){RestTemplate build = builder.build();return build;}

②程序中使用RestTemplate调用

    //注入RestTemplate@AutowiredRestTemplate restTemplate;@RequestMapping("/add")public String add(){System.out.println("下单成功");// String forObject = restTemplate.getForObject("http://localhost:8083/stock/reduct", String.class);String forObject = restTemplate.getForObject("http://stock-service/stock/reduct", String.class);return "add order "+forObject;}

现在使用OpenFeign调用:直接使用刚才创建的接口定义的方法

    @AutowiredStockOpenFeign stockOpenFeign;@RequestMapping("/add")public String add(){System.out.println("下单成功");String reduct = stockOpenFeign.reduct();return "add order "+reduct;}

3.Spring Cloud Feign日志配置

当我们遇到Bug,比如接口调用失败,参数没收到等问题,或者想看看调用性能问题,就需要配置Feign的性能日志,以此让Feign把请求信息输出来。

(1)Feign的日志级别有四种

①NONE【性能最佳,适用于生产】:不记录任何日志(默认)

②BASIC【适用于生产环境追踪问题】:仅记录请求方法,URL,响应状态代码及执行时间

③HEADERS:记录BASIC的基础上,记录请求和响应的header、

④FULL【比较适用于开发和测试环境定位问题】:记录请求和响应的header、body和元数据

(2)定义一个配置类,指定日志级别

/*** Feign配置类*/
public class FeignConfig {//指定日志级别@Beanpublic Logger.Level feignLoggerLever(){return Logger.Level.FULL;}
}

(3)application中配置日志级别

spring boot默认级别是info,feign需要配置为debug,所以默认级别情况下不输出feign日志,debug模式,日志太多,可以指定某个包下的日志配置成dubug。

(4)系统中再创建一个项目ProductNacos(商品管理系统),提供一个带参数@PathVariable 方式的访问服务。为了后面配置整体日志、指定某个日志方式做准备。

(5)使用Feign访问订单OrderNacos和商品ProductNacos项目的配置接口

/*** 使用@FeignClient来定义feign的调用方式,value为调用的服务名,path对应被调用服务处理的controller层*/
@FeignClient(value = "stock-service",path ="/stock" )
public interface StockOpenFeign {@RequestMapping("/reduct")String reduct();}
/*** 使用feign方式访问ProductNacos项目*/
@FeignClient(value = "product-service",path = "product")
public interface ProductOpenFeign {@RequestMapping("/{id}")String get(@PathVariable("id") Integer id);}

******当我们有参数时,使用@PathVariable时,需要把具体的参数名带上@PathVariable("id"),否则feign会报错,spring mvc请求时可以不带上具体的参数名。

(6)配置Feign的日志级别为全局方式,所有的服务都使用这个日志级别,在Feign日志配置类中加注解@Configuration

(7)我们的订单控制层,使用Feign的方式,调用库存Stock和商品Product的方式

@RestController
@RequestMapping("/order")
public class OrderController {@AutowiredStockOpenFeign stockOpenFeign;@AutowiredProductOpenFeign productOpenFeign;@RequestMapping("/add")public String add(){System.out.println("下单成功");String reduct = stockOpenFeign.reduct();String s = productOpenFeign.get(1);return "add order "+reduct+s;}
}

(8)访问服务,查看使用@Configuration全局配置日志的方式,控制台的输出情况:两个服务的feign调用日志都输出来了。

(9)feign日志指定某个服务调用时使用配置方式

需要先去除@Configuration配置

方式一:在Feign的配置接口中添加configuration指定

只有商品的日志信息打印出来了

方式二:在application.properties配置文件中指定

#feign日志局部配置:feign.client.config.服务名.logger-level=日志级别
feign.client.config.stock-service.logger-level=BASIC

此时只有stock服务调用有日志

4.Feign契约配置

Spring cloud在Feign的基础上做了扩展,使用Spring MVC注解的方式来完成Feign的功能。原生的Feign是不支持Spring mvc的,如果想在spring cloud客户端中使用原生的注解方式定义客户端也是可以的,通过配置契约来改变这个配置。

(1)修改契约配置,支持Feign原生的注解

  //修改契约配置,支持Feign原生的注解@Beanpublic Contract feignContract(){return new Contract.Default();}

注意:修改Feign的契约后,使用Feign连接的接口不在支持spring mvc的注解,需要使用Feign原生的注解

(2)Feign连接的接口使用原生的注解

RequestMapping需要改成RequestLine;@PathVariable需要改成@Param
@FeignClient(value = "product-service",path = "/product")
public interface ProductOpenFeign {@RequestLine("GET /{id}")String get(@Param("id") Integer id);}

(3)可以在application.properties配置文件中配置,局部指定某个服务使用原生feign配置

#feign契约局部配置:feign.client.config.服务名.contract=feign.Contract.Default
feign.client.config.product-service.contract=feign.Contract.Default

此时只是product-service这个配置了原生的feign,stock-service还是使用spring mvc的注解

5.Feign超时时间配置

通过Options可以设置连接超时时间和读取超时时间,Options的第一个参数是连接的超时时间(ms),模式2s;第二个参数是请求处理的超时时间(ms),默认5s。

(1)全局配置

    @Beanpublic Request.Options options(){return new Request.Options(5000,10000);}

(2)application.properties配置文件中进行局部配置

#feign连接超时时间局部配置:feign.client.config.服务名.connect-timeout=
feign.client.config.product-service.connect-timeout=5000#feign请求处理超时时间局部配置:feign.client.config.服务名.connect-timeout=
feign.client.config.product-service.read-timeout=10000

6.Open Feign自定义拦截器

(1)定义一个拦截器来,实现RequestInterceptor接口

/*** 自定义feign拦截器*/
public class FeignAuthRequestInterceptor implements RequestInterceptor {//重写拦截方法@Overridepublic void apply(RequestTemplate requestTemplate) {System.out.println("Feign拦截器拦截到信息");requestTemplate.uri("/8"); //改变请求的结尾链接}
}

(2)在配置类中使用@Configuration全局配置

    //配置自定义拦截器@Beanpublic FeignAuthRequestInterceptor feignAuthRequestInterceptor(){return new FeignAuthRequestInterceptor();}

(3)可以在application.properties配置文件中配置,局部配置

#feign请求处理超时时间局部配置:feign.client.config.服务名.request-interceptors[数组长度,支持多个拦截器]=自定义拦截器目录
feign.client.config.product-service.request-interceptors[0]=com.qingyun.inter.FeignAuthRequestInterceptor

(4)Feign发送请求前拦截控制台打印数据,修改uri的参数成功

7.Feign远程调用原理

Feign远程调用流程图

(1) 基于面向接口的动态代理方式生成实现类

在使用feign 时,会定义对应的接口类,在接口类上使用Http相关的注解,@FeignClient,标识HTTP请求参数信息,在Feign 底层,通过基于面向接口的动态代理方式生成实现类,将请求调用委托到动态代理实现类。

(2) 根据Contract协议规则,解析接口类的注解信息,解析分为默认的契约方式或者spring mvc的方式。

(3) 基于 RequestBean,动态生成Request

根据传入的Bean对象和注解信息,从中提取出相应的值,来构造Http Request 对象。

(4) 使用Encoder 将Bean转换成 Http报文正文(消息解析和转码逻辑)

Feign 最终会将请求转换成Http 消息发送出去,传入的请求对象最终会解析成消息体。

(5) 拦截器负责对请求和返回进行装饰处理

在请求转换的过程中,Feign 抽象出来了拦截器接口,用于用户自定义对请求的操作,比如,如果希望Http消息传递过程中被压缩,可以定义一个请求拦截器。

(6) 日志记录

(7) 基于重试器发送HTTP请求

Feign 内置了一个重试器,当HTTP请求出现IO异常时,Feign会有一个最大尝试次数发送请求

(8) 发送Http请求

Feign 真正发送HTTP请求是委托给 feign.Client 来做的。

Feign 默认底层通过JDK 的 java.net.HttpURLConnection 实现了feign.Client接口类,在每次发送请求的时候,都会创建新的HttpURLConnection 链接

(9)Feign优化

①GZIP压缩:当Gzip压缩到一个纯文本数据时,可以减少70%以上的数据大小。

②替换为HttpClient客户端(使用HTTP连接池提供性能)

Feign的HTTP客户端支持3种框架,分别是;HttpURLConnection、HttpClient、OKHttp。Feign中默认使用HttpURLConnection。

  • HttpURLConnection是JDK自带的HTTP客户端技术,并不支持连接池,如果要实现连接池的机制,还需要自己来管理连接对象。对于网络请求这种底层相对复杂的操作,如果有可用的其他方案,也没有必要自己去管理连接对象。
  • Apache提供的HttpClient框架相比传统JDK自带的HttpURLConnection,它封装了访问http的请求头,参数,内容体,响应等等;它不仅使客户端发送HTTP请求变得容易,而且也方便了开发人员测试接口(基于Http协议的),即提高了开发的效率,也方便提高代码的健壮性;另外高并发大量的请求网络的时候,还是用“HTTP连接池”提升吞吐量。
  • OKHttp是一个处理网络请求的开源项目,是安卓端最火热的轻量级框架。OKHttp拥有共享Socket,减少对服务器的请求次数,通过连接池,减少了请求延迟等技术特点。
  • feign.httpclient.enabled=true

Spring cloud alibaba--Feign微服务调用组件相关推荐

  1. Spring Cloud Alibaba 大型微服务项目实战

    作者介绍 程序员十三,多年一线开发经验,历任高级开发工程师.后端主程.技术部门主管等职位.同时也是开源项目的爱好者和贡献者.掘金优秀作者.CSDN 博客专家.实体图书作者.专栏作者.视频讲师. 小册介 ...

  2. 流量暴增,掌门教育如何基于 Spring Cloud Alibaba 构建微服务体系?

    作者 | 童子龙  掌门教育基础架构部架构师 **导读:**本文整理自作者于 2020 年云原生微服务大会上的分享<掌门教育云原生落地实践>,本文主要介绍了掌门教育云原生落地实践,主要围绕 ...

  3. Spring Cloud Alibaba 新一代微服务解决方案

    本篇是「跟我学 Spring Cloud Alibaba」系列的第一篇, 每期文章会在公众号「架构进化论」进行首发更新,欢迎关注. 1.Spring Cloud Alibaba 是什么 Spring ...

  4. Spring Cloud Alibaba - 15 微服务之间使用Feign实现参数的透传

    文章目录 业务场景 实现 自定义拦截器 暴漏接口 服务实现 服务调用者 验证 源码 业务场景 服务A 获取到Token值后,要传递给 服务B进行校验 . 在微服务架构下如何实现呢? 实现 自定义拦截器 ...

  5. 用Spring Cloud Alibaba开发微服务会更香吗?

    关注DD,除了前沿消息,还有每周福利哦 Spring Cloud Alibaba致力于提供微服务开发的一站式解决方案,它是Spring Cloud组件被植入Alibaba元素之后的产物. 利用Spri ...

  6. 【Spring Cloud Alibaba】(二)微服务调用组件Feign原理+实战

    系列目录 [Spring Cloud Alibaba](一)微服务介绍 及 Nacos注册中心实战 本文目录 系列目录 前言 什么是RPC? Feign和OpenFeign都是什么? HTTP调用 v ...

  7. com 组件调用不起来_Spring Cloud Alibaba训练营 —— 分布式服务调用

    注意:用手机查看排版可能不太友好, 1. 简介 在<Spring Cloud Alibaba 服务注册与发现>篇中曾提到,Spring Cloud Alibaba Nacos Discov ...

  8. com 组件调用不起来_Spring Cloud Alibaba,分布式服务调用(四)

    1. 简介 在<Spring Cloud Alibaba 服务注册与发现>篇中曾提到,Spring Cloud Alibaba Nacos Discovery 能无缝整合 Spring C ...

  9. 进击的 Spring Cloud Alibaba —— 框架与服务

    作者 | 陈曦(良名)  Spring Cloud Alibaba 项目成员,start.aliyun.com 负责人. 导读:本文整理自作者于 2020 年云原生微服务大会上的分享<进击的 S ...

  10. Spring Cloud与Docker微服务架构实战 PDF版 内含目录

    Spring Cloud与Docker微服务架构实战  目录 1 微服务架构概述 1 1.1 单体应用架构存在的问题1 1.2 如何解决单体应用架构存在的问题3 1.3 什么是微服务3 1.4 微服务 ...

最新文章

  1. 使用域用户权限|安装软件
  2. linux中shell变量$#,$@,$0,$1,$2的含义解释
  3. group by的查询
  4. 将InputStream写入本地文件
  5. [转载]非常量引用的初始值必须为左值的问题
  6. [云炬创业基础笔记] 第四章测试14
  7. 分享几道经典的javascript面试题
  8. python 结构数组_Python-“结构数组”
  9. C++ 封装DLL遇到的一些坑爹问题与解决方案
  10. 三星Galaxy S10系列外观配置爆料:多种颜色可选
  11. 追风猎洞只能喝西北风吗?
  12. linux下alias命令具体解释
  13. android app入口函数,Android App程序运行过程 ActivityThread.main()------详解系列(一)...
  14. 想要给视频去色有什么方法?原来用这个就可以了
  15. (转)几个开源的视频编解码器介绍
  16. C/C++中各类数值型数据间的混合运算法则
  17. win10计算机系统优化设置,小编教你windows10设置优化提高系统性能
  18. wireshark抓包新手使用教程
  19. Android View的事件分发机制和滑动冲突解决方案
  20. pymysql数据库的水果店销售系统之管理员端1.0

热门文章

  1. linux重新初始化网络命令,如何在Ubuntu 18.04 Bionic Beaver Linux上重新启动网络
  2. 『Linux』Ubuntu Beaver(18.04) 配置 美化流程
  3. zoc 下载服务器上数据出现的问题
  4. This must be due to duplicate classes or playing wrongly with class loaders 1
  5. 人在旅途——》张家界之旅:20190420
  6. 新加坡国立大学尤洋:我的四个选择,本质的喜欢催动长久的坚持丨青源专栏...
  7. mysql中gt用法_讲解MySQL中lt;=gt;操作符的用法-一团网
  8. 资讯的服务器维护指什么,资讯
  9. 异地远程群晖NAS教程【cpolar内网穿透】
  10. 表单提交后跳转指定链接