Spring cloud alibaba--Feign微服务调用组件
目录
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微服务调用组件相关推荐
- Spring Cloud Alibaba 大型微服务项目实战
作者介绍 程序员十三,多年一线开发经验,历任高级开发工程师.后端主程.技术部门主管等职位.同时也是开源项目的爱好者和贡献者.掘金优秀作者.CSDN 博客专家.实体图书作者.专栏作者.视频讲师. 小册介 ...
- 流量暴增,掌门教育如何基于 Spring Cloud Alibaba 构建微服务体系?
作者 | 童子龙 掌门教育基础架构部架构师 **导读:**本文整理自作者于 2020 年云原生微服务大会上的分享<掌门教育云原生落地实践>,本文主要介绍了掌门教育云原生落地实践,主要围绕 ...
- Spring Cloud Alibaba 新一代微服务解决方案
本篇是「跟我学 Spring Cloud Alibaba」系列的第一篇, 每期文章会在公众号「架构进化论」进行首发更新,欢迎关注. 1.Spring Cloud Alibaba 是什么 Spring ...
- Spring Cloud Alibaba - 15 微服务之间使用Feign实现参数的透传
文章目录 业务场景 实现 自定义拦截器 暴漏接口 服务实现 服务调用者 验证 源码 业务场景 服务A 获取到Token值后,要传递给 服务B进行校验 . 在微服务架构下如何实现呢? 实现 自定义拦截器 ...
- 用Spring Cloud Alibaba开发微服务会更香吗?
关注DD,除了前沿消息,还有每周福利哦 Spring Cloud Alibaba致力于提供微服务开发的一站式解决方案,它是Spring Cloud组件被植入Alibaba元素之后的产物. 利用Spri ...
- 【Spring Cloud Alibaba】(二)微服务调用组件Feign原理+实战
系列目录 [Spring Cloud Alibaba](一)微服务介绍 及 Nacos注册中心实战 本文目录 系列目录 前言 什么是RPC? Feign和OpenFeign都是什么? HTTP调用 v ...
- com 组件调用不起来_Spring Cloud Alibaba训练营 —— 分布式服务调用
注意:用手机查看排版可能不太友好, 1. 简介 在<Spring Cloud Alibaba 服务注册与发现>篇中曾提到,Spring Cloud Alibaba Nacos Discov ...
- com 组件调用不起来_Spring Cloud Alibaba,分布式服务调用(四)
1. 简介 在<Spring Cloud Alibaba 服务注册与发现>篇中曾提到,Spring Cloud Alibaba Nacos Discovery 能无缝整合 Spring C ...
- 进击的 Spring Cloud Alibaba —— 框架与服务
作者 | 陈曦(良名) Spring Cloud Alibaba 项目成员,start.aliyun.com 负责人. 导读:本文整理自作者于 2020 年云原生微服务大会上的分享<进击的 S ...
- Spring Cloud与Docker微服务架构实战 PDF版 内含目录
Spring Cloud与Docker微服务架构实战 目录 1 微服务架构概述 1 1.1 单体应用架构存在的问题1 1.2 如何解决单体应用架构存在的问题3 1.3 什么是微服务3 1.4 微服务 ...
最新文章
- 使用域用户权限|安装软件
- linux中shell变量$#,$@,$0,$1,$2的含义解释
- group by的查询
- 将InputStream写入本地文件
- [转载]非常量引用的初始值必须为左值的问题
- [云炬创业基础笔记] 第四章测试14
- 分享几道经典的javascript面试题
- python 结构数组_Python-“结构数组”
- C++ 封装DLL遇到的一些坑爹问题与解决方案
- 三星Galaxy S10系列外观配置爆料:多种颜色可选
- 追风猎洞只能喝西北风吗?
- linux下alias命令具体解释
- android app入口函数,Android App程序运行过程 ActivityThread.main()------详解系列(一)...
- 想要给视频去色有什么方法?原来用这个就可以了
- (转)几个开源的视频编解码器介绍
- C/C++中各类数值型数据间的混合运算法则
- win10计算机系统优化设置,小编教你windows10设置优化提高系统性能
- wireshark抓包新手使用教程
- Android View的事件分发机制和滑动冲突解决方案
- pymysql数据库的水果店销售系统之管理员端1.0
热门文章
- linux重新初始化网络命令,如何在Ubuntu 18.04 Bionic Beaver Linux上重新启动网络
- 『Linux』Ubuntu Beaver(18.04) 配置 美化流程
- zoc 下载服务器上数据出现的问题
- This must be due to duplicate classes or playing wrongly with class loaders 1
- 人在旅途——》张家界之旅:20190420
- 新加坡国立大学尤洋:我的四个选择,本质的喜欢催动长久的坚持丨青源专栏...
- mysql中gt用法_讲解MySQL中lt;=gt;操作符的用法-一团网
- 资讯的服务器维护指什么,资讯
- 异地远程群晖NAS教程【cpolar内网穿透】
- 表单提交后跳转指定链接