03-基于Feign的远程调用,详解Feign的自定义配置和优化,创建Feign模块

Feign远程调用

Feign替代RestTemplate

利用RestTemplate发起远程调用的代码的缺点

  • 代码可读性差编程体验不统一 , 面对参数复杂的URL难以维护
String url = "http://user-service/user/" + order.getUserId();
User user = restTemplate.getForObject(url, User.class);

Feign是一个声明式的http客户端,我们只需要把发请求需要的信息声明出来如请求方式,请求路径,请求参数等信息,剩下的由Fegin帮我们完成http请求的发送

第一步引入依赖:在order-service模块的pom文件中引入Feign的依赖spring-cloud-starter-openfeign

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

第二步开启Feign的功能:在order-service模块的启动类上添加@EnableFeignClients注解

第三步编写Feign客户端代码:在order-service模块的com.itcast.order.client包下新建UserClient接口,基于SpringMVC的注解来声明远程调用的信息

请求信息举例
请求的服务名称user-service
请求的方式GET或POST
请求的路径/user/{id}
请求的参数如用户的d
请求响应的返回值类型如User对象
// 封装了对user-service服务的远程调用的信息
@FeignClient("user-service")
public interface UserClient {@GetMapping("/user/{id}")User findById(@PathVariable("id") Long id);
}

第四步编写业务逻辑代码: 在order-service模块的OrderService类中的queryOrderById方法使用Feign客户端代替RestTemplate

第五步: 使用浏览器发起请求http://localhost:8080/order/101实现Fegin的远程调用

  • 观察user-service服务对应的多个实例的控制台信息,可以发现Feign不仅实现了远程调用还实现了负载均衡功能(因为内部集成了Ribbo组件)
@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;// 注入Feign的客户端@Autowiredprivate UserClient userClient;public Order queryOrderById(Long orderId) {// 1. 查询订单Order order = orderMapper.findById(orderId);// 2. 利用Feign的客户端发起http请求访问user-service查询用户信息User user = userClient.findById(order.getUserId());// 3. 封账user对象到order对象的user属性中order.setUser(user);// 4. 返回order对象return order;}
}

Feign的自定义配置

Feign可以支持很多的自定义配置但一般情况下默认值就能满足我们的使用,如果需要自定义配置只需要创建自定义的@Bean覆盖默认的Bean即可

类型作用说明
feign.Logger.Level修改日志级别,包含四种不同的级别NONE(默认值,不记录任何日志信息,提升性能)
BASIC(仅记录请求的方法,URL以及响应状态码和执行时间)
HEADERS(在BASIC的基础上额外记录了请求和响应头的信息)
FULL(记录所有请求和响应的明细包括头信息、请求体、元数据,调试时使用)
feign.codec.Decoder响应结果的解析器http远程调用的结果做解析,例如解析json字符串为java对象
feign.codec.Encoder请求参数编码将请求参数编码便于通过http请求发送
feign. Contract支持的注解格式默认是SpringMVC的注解
feign. Retryer失败重试机制(某个服务实例查询不到就换个服务实例)请求失败的重试机制(默认是没有),不过会使用Ribbon的重试

基于order-service模块的application,yml配置文件自定义日志配置

# 针对某个微服务的配置
feign:  client:config: user-service: # 针对配置的服务名称loggerLevel: FULL #  日志级别
# 针对所有服务的配置        
feign:  client:config: default: # default就是全局配置针对所有服务loggerLevel: FULL #  日志级别         

基于Java代码自定义日志配置: 先声明一个配置类(不用加注解), 然后声明一个Logger.Level的对象

  • 全局生效: 将配置类放到启动类的@EnableFeignClients注解中@EnableFeignClients(defaultConfiguration = DefaultFeignConfiguration.class)
  • 局部生效: 将配置类放到对应@FeignClient注解中@FeignClient(value = "user-service", configuration = DefaultFeignConfiguration.class)
public class DefaultFeignConfiguration {@Beanpublic Logger.Level feignLogLevel(){return Logger.Level.BASIC; //日志级别设置为 BASIC}
}

Feign的使用优化

Feign底层发起http请求需要依赖于其他框架, 其底层客户端实现包括三种,提高Frign的性能主要手段就是使用连接池代替默认的URLConnection

  • URLConnection: Feign底层默认会使用JDK自带的客户端但不支持连接池
  • Apache HttpClient: 支持连接池
  • OKHttp: 支持连接池

优化Feign性能的两种方式

  • 日志级别尽量使用BASIC或NONE
  • 使用支持连接池的HttpClient或OKHttp代替URLConnection

第一步引入依赖: 在order-service模块的pom文件中引入Apache的HttpClient依赖

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

第二步配置连接池: 在order-service模块的application.yml文件中添加配置,开启httpclient功能设置相关的连接池参数

feign:client:config:default: # default全局的配置logger-level: BASIC # 日志级别,BASIC就是基本的请求和响应信息httpclient:enabled: true # 开启feign对HttpClient的支持(默认是true,即如果引入了HttpClient依赖就可以使用)max-connections: 200 # 请求的最大的连接数max-connections-per-route: 50 # 分配给每个请求路径的最大连接数	

继承(面向契约思想)

由于Feign的客户端方法与服务提供者user-servie模块中UserController中对应的接口方法的代码除了方法名不同其余几乎一模一样

  • order-service模块基于Feign的客户端UserClient中定义的方法发起请求,user-servie模块接收并处理order-service模块发起的请求
@FeignClient(value = "user-service",configuration = DefaultFeignConfiguration.class)
public interface UserClient {@GetMapping("/user/{id}")User findById(@PathVariable("id") Long id);
}
@RestController
@RequestMapping("/user")
@RefreshScope
public class UserController {@Autowiredprivate UserService userService;@GetMapping("/{id}")public User queryById(@PathVariable("id") Long id) {return userService.queryById(id);}
}

第一步: 通过继承来共享Feign客户端和Controller中相同的代码,先定义一个API接口, 通过定义接口方法并基于SpringMVC注解的方式声明发送Http请求的信息

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

第二步: Feign的客户端UserClient继承定义好的UserAPI接口,而UserController实现UserAPI接口

@FeignClient(value = "user-service")
public interface UserClient extends UserAPI{}
@RestController
public class UserController implents UserAPI{public User findById(@PathVariable("id") Long id){// ...实现业务逻辑}
}

基于继承方式的优缺点

  • 优点: 简单并且实现了代码共享

  • 缺点: 服务提供方和服务消费方紧耦合, 参数列表中的注解映射并不会继承,所以Controller中需要再次声明方法、参数列表、注解

基于抽取的最佳实践

Feign的客户端抽取为独立模块,并且把接口有关的POJO和默认的Feign配置都放到这个模块中,服务消费者引用该依赖包后即可使用

  • 缺点: 如果某个微服务只想要使用模块的部分功能也要把整个模块引入

在这里插入图片描述

第一步: 创建一个新的modulefeign-api模块并在pom.xml文件中引入feign的starter依赖spring-cloud-starter-openfeign

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

第二步: 将order-service模块中编写的UserClient、User、DefaultFeignConfiguration都转移到feign-api模块中
第三步: 在order-service模块中的pom.xml文件中引入我们自己编写的依赖feign-api

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

解决自动注入失败问题: order-service模块的@EnableFeignClients注解是在cn.itcast.order包下显然无法扫描到cn.itcast.feign.clients包下的UserClient

// 方式一:指定Feign应该扫描的包
@EnableFeignClients(basePackages = "cn.itcast.feign.clients")// 方式二: 指定需要加载的XxxClient接口
@EnableFeignClients(clients = {UserClient.class})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/156983.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

相对定位、绝对定位、固定定位、绝对定位堆叠顺序

相对定位&#xff1a;相对自己本身进行偏移 CSS语法&#xff1a; position: relative;/*相对自己进行定位*/ top: 10px;/*距离上边*/ left: 10px;/*距离左边*/ 演示图&#xff1a; 绝对定位&#xff1a;默认以浏览器进行定位。如果想依照父盒子定位&#xff0c;需要在父盒子…

STM32 寄存器配置笔记——USART配置 打印

一、概述 本文主要介绍如何配置USART&#xff0c;并通过USART打印验证结果。以stm32f10为例&#xff0c;将PA9、PA10复用为USART功能&#xff0c;使用HSE PLL输出72MHZ时钟 APB2 clk不分频提供配置9600波特率。波特率计算公式如下&#xff1a; fck即为APB2 clk参考计算&#xf…

ppt录屏制作微课,轻松打造精品课程

微课作为一种新型的教学方式逐渐受到广大师生的欢迎。微课具有方便快捷、内容丰富、互动性强等特点&#xff0c;可以有效地帮助教师传达知识&#xff0c;提高学生的学习效果。其中&#xff0c;ppt录屏制作微课就是一种常见的方式。本文将介绍ppt录屏的使用方法&#xff0c;帮助…

七天.NET 8操作SQLite入门到实战 - 第二天 在 Windows 上配置 SQLite环境

前言 SQLite的一个重要的特性是零配置的、无需服务器&#xff0c;这意味着不需要复杂的安装或管理。它跟微软的Access差不多&#xff0c;只是一个.db格式的文件。但是与Access不同的是&#xff0c;它不需要安装任何软件&#xff0c;非常轻巧。 七天.NET 8操作SQLite入门到实战…

第十二章 pytorch中使用tensorboard进行可视化(工具)

PyTorch 从 1.2.0 版本开始&#xff0c;正式自带内置的 Tensorboard 支持了&#xff0c;我们可以不再依赖第三方工具来进行可视化。 tensorboard官方教程地址&#xff1a;https://github.com/tensorflow/tensorboard/blob/master/README.md 1、tensorboard 下载 step 1 此次…

解锁电力安全密码:迅软DSE助您保护机密无忧

电力行业信息化水平不断提高&#xff0c;明显提升了电力企业的生产运营能力&#xff0c;然而随着越来越多重要信息存储在终端计算机中&#xff0c;电力面临的信息安全挑战也越来越多。 作为关键基础设施的基础&#xff0c;电力企业各部门产生的资料文档涵盖着大量机密信息&…

1.Qt5.15及其以上的下载

Qt5.15及其以上的下载 简介&#xff1a; ​ Qt是一个跨平台的C库&#xff0c;允许开发人员创建在不同操作系统&#xff08;如Windows、macOS、Linux/Unix&#xff09;和设备上具有本地外观和感觉的应用程序。Qt提供了一套工具和库&#xff0c;用于构建图形用户界面&#xff0…

【Linux】 find命令使用

find find命令是一种通过条件匹配在指定目录下查找对应文件或者目录的工具。匹配的条件可以是文件名称、类型、大小、权限属性、时间戳等。find命令还可以配合相关命令对匹配到的文件作出后续处理。 语法 find [路径...] [表达式] [path...]为需要查找文件所指定的路径。如果…

智能座舱架构与芯片- (12) 软件篇 中

三、智能座舱操作系统 3.1 概述 车载智能计算平台自下而上可大致划分为硬件平台、系统软件&#xff08;硬件抽象层OS内核中间件&#xff09;、功能软件&#xff08;库组件中间件&#xff09;和应用算法软件等四个部分。狭义上的OS特指可直接搭载在硬件上的OS内核&#xff1b;…

【C++进阶之路】第十一篇:C++的IO流

文章目录 1. C语言的输入与输出2. 流是什么3. CIO流3.1 C标准IO流3.2 C文件IO流 4.stringstream的简单介绍 1. C语言的输入与输出 C语言中我们用到的最频繁的输入输出方式就是scanf ()与printf()。 scanf(): 从标准输入设备(键盘)读取数据&#xff0c;并将值存放在变量中。prin…

易航网址引导系统 v1.9 源码:去除弹窗功能的易航网址引导页管理系统

易航自主开发了一款极其优雅的易航网址引导页管理系统&#xff0c;后台采用全新的光年 v5 模板开发。该系统完全开源&#xff0c;摒弃了后门风险&#xff0c;可以管理无数个引导页主题。数据管理采用易航原创的JsonDb数据包&#xff0c;无需复杂的安装解压过程即可使用。目前系…

SVN创建分支

一 从本地创建方式可指定版本号进行分支创建。 1、在本地目录右击 -----> 点击branch/tag(分支/标签) From: 源&#xff0c;可指定具体的版本号&#xff0c; To path: 可通过"..."选择分支路径 最后点击确定&#xff0c;交由服务器执行创建。 二 通过SVN客…

html实现计算器源码

文章目录 1.设计来源1.1 主界面1.2 计算效果界面 2.效果和源码2.1 动态效果2.2 源代码 源码下载 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/article/details/134532725 html实现计算器源码&#xff0c;计算器源码&#xff0c;简易计…

11.21序列检测,状态机比较与代码,按键消抖原理

序列检测 用一个atemp存储之前的所有状态&#xff0c;即之前出现的七位 含无关项检测 要检测011XXX110 对于暂时变量的高位&#xff0c;位数越高就是越早出现的数字&#xff0c;因为新的数字存储在TEMP的最低位 不重叠序列检测 &#xff0c;一组一组 011100 timescale 1ns…

【算法】二分查找-20231122

这里写目录标题 一、1089. 复写零二、917. 仅仅反转字母三、88. 合并两个有序数组四、283. 移动零 一、1089. 复写零 提示 简单 266 相关企业 给你一个长度固定的整数数组 arr &#xff0c;请你将该数组中出现的每个零都复写一遍&#xff0c;并将其余的元素向右平移。 注意&a…

智能座舱架构与芯片- (13) 软件篇 下

四、面向服务的智能座舱软件架构 4.1 面向信号的软件架构 随着汽车电子电气架构向中央计算-域控制器的方向演进&#xff0c;甚至向车云一体化的方向迈进&#xff0c;适用于汽车的软件平台也需要进行相应的进化。 在传统的观念中&#xff0c;座舱域即娱乐域&#xff0c;座舱软…

4.Gin HTML 模板渲染

4.Gin HTML 模板渲染 Gin HTML 模板渲染 1. 全部模板放在一个目录里面的配置方法 创建用于渲染的模板html templates/index.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> …

【GitHub】保姆级使用教程

一、如何流畅访问GitHub 1、网易uu加速器 输入网址&#xff0c;无脑下载网易加速器&#xff1b;https://uu.163.com/ 下载安装完毕后&#xff0c;创建账号进行登录 登录后&#xff0c;在右上角搜索框中搜索“学术资源”&#xff0c;并点击&#xff1b; 稍等一会儿就会跳…

如何在3dMax中使用Python按类型选择对象?

如何在3dMax中使用Python按类型选择对象&#xff1f; 3dMax提供了pymxs API&#xff0c;这是MAXScript的Python包装器&#xff0c;可帮助您扩展和自定义3dMax&#xff0c;并更轻松地将其集成到基于Python的管道中。 pymxs模块包含一个运行时成员&#xff0c;该成员提供对MAXSc…

电子学会C/C++编程等级考试2022年09月(一级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:指定顺序输出 依次输入3个整数a、b、c,将他们以c、a、b的顺序输出。 时间限制:1000 内存限制:65536输入 一行3个整数a、b、c,以空格分隔。 0 < a,b,c < 108输出 一行3个整数c、a、b,整数之间以一个空格分隔。样例输入…