网站用什么字体,网站首页外链,大的互联网公司,长宁区网站建设公司第七章 Feign 远程调用
先来看我们以前利用 RestTemplate 发起远程调用的代码#xff1a; 存在下面的问题#xff1a; 代码可读性差#xff0c;编程体验不统一 参数复杂 URL 难以维护 Feign 是一个声明式的 http 客户端#xff0c;官方地址#xff1a;https://github.…第七章 Feign 远程调用
先来看我们以前利用 RestTemplate 发起远程调用的代码 存在下面的问题 代码可读性差编程体验不统一 参数复杂 URL 难以维护 Feign 是一个声明式的 http 客户端官方地址https://github.com/OpenFeign/feign 其作用就是帮助我们优雅的实现 http 请求的发送解决上面提到的问题。 一、Feign 替代 RestTemplate
Fegin 的使用步骤如下
1. 引入依赖
我们在 order-service 服务的 pom 文件中引入 feign 的依赖
dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-openfeign/artifactId
/dependency2. 添加注解
在 order-service 的启动类添加注解开启 Feign 的功能 3. 编写 Feign 的客户端
在 order-service 中新建一个接口内容如下
package com.alex.order.client;import com.alex.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 是不是看起来优雅多了。
5. 总结 使用 Feign 的步骤 ① 引入依赖 ② 添加EnableFeignClients 注解 ③ 编写 FeignClient 接口 ④ 使用 FeignClient 中定义的方法代替 RestTemplate
二、自定义配置
Feign 可以支持很多的自定义配置如下表所示
类型作用说明feign.Logger.Level修改日志级别包含四种不同的级别NONE、BASIC、HEADERS、FULLfeign.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 代码方式
也可以基于 Java 代码来修改日志级别先声明一个类然后声明一个 Logger.Level 的对象
public class DefaultFeignConfiguration {Beanpublic 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的依赖 --
dependencygroupIdio.github.openfeign/groupIdartifactIdfeign-httpclient/artifactId
/dependency2. 配置连接池
在 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 3. 总结 Feign 的优化 日志级别尽量用 basic 使用 HttpClient 或 OKHttp 代替 URLConnection 引入 feign-httpClient 依赖 配置文件开启 httpClient 功能设置连接池参数
四、最佳实践 所谓最佳实践就是使用过程中总结的经验最好的一种使用方式。 观察可以发现Feign 的客户端与服务提供者的 controller 代码非常相似 feign 客户端 UserController 有没有一种办法简化这种重复的代码编写呢
1. 继承方式 一样的代码可以通过继承来共享 定义一个 API 接口利用定义方法并基于 SpringMVC 注解做声明。 Feign 客户端和 Controller 都集成改接口 优点 简单实现了代码共享 缺点 服务提供方、服务消费方紧耦合 参数列表中的注解映射并不会继承因此 Controller 中必须再次声明方法、参数列表、注解
2. 抽取方式 将 Feign 的 Client 抽取为独立模块并且把接口有关的 POJO、默认的 Feign 配置都放到这个模块中提供给所有消费者使用。 例如将 UserClient、User、Feign 的默认配置都抽取到一个 feign-api 包中所有微服务引用该依赖包即可直接使用。 3. 实现基于抽取的最佳实践
3.1 抽取
首先创建一个 module命名为 feign-api 项目结构 在 feign-api 中然后引入 feign 的 starter 依赖
dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-openfeign/artifactId
/dependency然后order-service 中编写的 UserClient、User、DefaultFeignConfiguration 都复制到 feign-api 项目中 3.2 在 order-service 中使用 feign-api 首先删除 order-service 中的 UserClient、User、DefaultFeignConfiguration 等类或接口。 在 order-service 的 pom 文件中中引入 feign-api 的依赖
dependencygroupIdcom.alex.demo/groupIdartifactIdfeign-api/artifactIdversion1.0/version
/dependency修改 order-service 中的所有与上述三个组件有关的导包部分改成导入 feign-api 中的包
3.3 重启测试
重启后发现服务报错了 这是因为 UserClient 现在在 com.alex.feign.clients 包下 而 order-service 的EnableFeignClients 注解是在 com.alex.order 包下不在同一个包无法扫描到 UserClient。
3.4 解决扫描包问题
3.4.1 方式一
指定 Feign 应该扫描的包
EnableFeignClients(basePackages com.alex.feign.clients)3.4.2 方式二
指定需要加载的 Client 接口
EnableFeignClients(clients {UserClient.class})