微服务:Feign篇

1.什么是Feign

Feign是一种声明式、模板化的HTTP客户端,可用于调用HTTP API实现微服务之间的远程服务调用。它的特点是使用少量的配置定义服务客户端接口,可以实现简单和可重用的RPC调用。

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

存在下面的问题:

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

•参数复杂URL难以维护

2. Feign远程调用

2.1. Feign替代RestTemplate

Fegin的使用步骤如下:

2.1.1. 引入依赖

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

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

2.1.2. 添加注解

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

2.1.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来发送了。

2.1.4. 测试

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

是不是看起来优雅多了。

5)总结

使用Feign的步骤:

① 引入依赖

② 添加@EnableFeignClients注解

③ 编写FeignClient接口

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

2.2 Feign的自定义配置

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) 

3. Feign最佳实践

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

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

feign客户端:

UserController:

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

当然有:

3.1. 继承方式(不推荐)

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

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

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

优点:

  • 简单

  • 实现了代码共享

缺点:

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

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

3.2. 抽取方式

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

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

3.3. 基于抽取的最佳实践

3.3.1. 抽取

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

项目结构:

在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.3.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.3.3. 重启测试

重启时,发现服务报错:

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

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

3.3.4. 解决扫描包的问题

方式1(不推荐):

指定Feign应该扫描的包:

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

方式二:

指定需要加载的Client接口:

@EnableFeignClients(clients = {UserClient.class})

3.3.5. 重启

重启,测试结果

成功!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

卡密交易系统 卡密社区SUP系统源码 分销系统平台 分销商城系统开发

卡密社区SUP系统总控源码主站分销系统功能源码 跟以前的卡盟那种控制端差不多总控可以给别人开通&#xff0c;分销&#xff0c;主站&#xff0c;类似自己做系统商一样&#xff0c;自助发卡&#xff0c;卡密交易系统。 搭建环境Nginx1.22 mysql 5.7 php8.1 rids 7.2 安装方法…

【C++】十大排序算法之 插入排序 希尔排序

本次介绍内容参考自&#xff1a;十大经典排序算法&#xff08;C实现&#xff09; - fengMisaka - 博客园 (cnblogs.com) 排序算法是《数据结构与算法》中最基本的算法之一。 十种常见排序算法可以分为两大类&#xff1a; 比较类排序&#xff1a;通过比较来决定元素间的相对次序…

鸿蒙开发就业前景以及发展方向分析~

鸿蒙操作系统作为华为公司自主研发的操作系统&#xff0c;已经成为当下炙手可热的话题。作为一个全新的操作系统&#xff0c;鸿蒙开发为IT行业带来了巨大的就业机会。本文将围绕鸿蒙开发的就业前景以及发展方向展开讨论。 一、鸿蒙开发就业前景 随着鸿蒙操作系统的发布&#…

二叉树——从中序与后序遍历序列构造二叉树、654. 最大二叉树、617. 合并二叉树

从中序与后序遍历序列构造二叉树 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 在这里插入代码片 输入&#xff1a;inorder [9,3,15…

leetcode 热题 100_和为 K 的子数组

题解一&#xff1a; 前缀和数组哈希表&#xff1a;可以计算所有子数组之和暴力求解&#xff0c;但复杂度太高。对于子数组求和的过程&#xff0c;我们可以采用前缀和数组进行优化&#xff0c;前缀和数组中pre[index]代表nums[0]~nusm[index]之和&#xff0c;当我们要计算子数组…

NLP评价指标

一、分类任务常见评估&#xff1a; 准确度(Accuracy) 评估预测正确的比例&#xff0c;精确率(Precision) 评估预测正例的查准率&#xff0c;召回率(Recall) 评估真实正例的查全率。如果是多分类&#xff0c;则每个类别各自求P、R最终求平均值。 TP&#xff08;True Positives…

SwiftUI 在 App 中弹出全局消息横幅(上)

功能需求 在 SwiftUI 开发的 App 界面中,有时我们需要在全局层面向用户展示一些消息: 如上图所示:我们弹出的全局消息横幅位于所有视图之上,这意味这它不会被任何东西所遮挡;而且用户可以点击该横幅关闭它。这是怎么做到的呢? 在本篇博文中,您将学到以下内容 功能需求…

mac电脑使用pyinstaller打包python脚本

pyinstaller -F template.py 出现报错"AssertionError: Executable contains code signature!" 移除签名 codesign --remove-signature /Users/f7692281/PycharmProjects/TPtestlist/transmit_v6.0.py 打包命令 pyinstaller --windowed transmit_v6.0.py pyinst…

如何使用两个 ESP32-DevKit 开发板的 SDIO 接口测试 AT 固件?

文档参考 ESP32 SDIO AT GuideSDIO 硬件接线说明 硬件准备 两个 ESP32-DevKit 开发板10 KHz 电阻长度低于 10cm 的杜邦线 管脚ESP32 SDIO HostESP32 SDIO SlaveCLK1414CMD1515DAT022DAT144DAT21212DAT31313GNDGNDGND 1-bit SD 模式&#xff08;默认&#xff09;&#xff1…

HTTP代理扫描的技术解析(HTTP代理扫描的技术原理和使用方法)

HTTP代理扫描的技术解析 近年来&#xff0c;随着互联网的快速发展&#xff0c;HTTP代理扫描技术也日益成熟。HTTP代理扫描是指通过扫描网络中的HTTP代理服务器&#xff0c;获得有效代理的IP地址和端口&#xff0c;进而实现网络请求的转发。通过HTTP代理扫描&#xff0c;用户可…

深入了解直播美颜SDK,美颜SDK是什么?

在实现直播美颜功能的背后&#xff0c;美颜SDK扮演了重要的角色。今天&#xff0c;笔者将为大家讲解美颜SDK的定义、功能以及在直播行业中的应用。 一、美颜SDK的定义 美颜SDK是一种软件开发工具包&#xff0c;旨在为应用开发者提供一套实现美颜功能的接口和算法。它通常包含…

探究java反射取值与方法取值性能对比

探究java反射取值与方法取值性能对比 由于我开发框架时&#xff0c;经常需要对象取值。常用的取值方式有&#xff1a; 反射取值方法调用取值 环境 同一台电脑&#xff1a; jdk 21.0.2 idea 2023.3.3 1. 测试代码&#xff08;常用&#xff09; 1.1 反射取值 public stat…

从零开始手写RPC框架(4)

这一节主要讲述网络传输模块的代码&#xff0c;并且几乎每一行代码都加上了我个人理解的注释&#xff0c;同时也讲述了其中一些以前没见过的函数&#xff0c;和大致的底层运行逻辑。 目录 网络传输实体类网络传输实现基于Socket实现网络传输基于Netty实现网络传输客户端服务端 …

华为---MSTP(一)---MSTP生成树协议

目录 1. MSTP技术产生背景 2. STP/RSTP的缺陷 ​编辑 2.1 无法均衡流量负载 2.2 数据使用次优路径 3. MSTP生成树协议 3.1 MSTP相关概念 3.2 MSTP树生成的形成过程 4. MSTP报文 1. MSTP技术产生背景 RSTP在STP基础上进行了改进&#xff0c;实现了网络拓扑快速收敛。但…

【k8s管理--可视化界面】

1、可视化界面的软件 kubernetes的可视化软件有以下这些kubernetes dashboard&#xff1a;https://github.com/kubernetes/dashboardkubesphere官网&#xff1a; https://kubesphere.io/zh/rancher 官网&#xff1a; https://www.rancher.cn/kuboard 官网&#xff1a; https:/…

C++11常用知识分享(一)【列表初始化 || 简化声明 || 范围for || 左右值 || 可变参数模板】

目录 一. 列表初始化 1&#xff09;用法 2) initializer_list 小节&#xff1a; 二&#xff0c;简化声明 1) &#xff0c;auto 2) &#xff0c;decltype类 3)&#xff0c;nullptr 三&#xff0c;范围for 四&#xff0c;C11后&#xff0c;STL容器变化 五&#xff0c…

【数据结构】实现堆

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家了解堆&#xff0c;如果你觉得我写的还不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 目录 一. 堆的概念及结构二. 堆的实现堆的结构体初始化销毁插入数据删除数据&#xff08;默认删除堆顶即…

【JS】WebSocket实现简易聊天室

【JS】WebSocket实现简易聊天室 聊天室思路示例 聊天室思路 聊天室思路 1、连接服务器先建立连接&#xff0c;默认生成匿名用户(admin01) 2、客户端发送消息&#xff0c;其它客户端用户都会同步接收消息(服务端接受消息广播所有连接用户) 3、客户端修改昵称&#xff0c;其它客…

鸿蒙应用组件

基础组件 索引组件—AlphabetIndexer&#xff08;相当于安卓的seedbar&#xff09; 使用&#xff1a;AlphabetIndexer(value: {arrayValue: Array<string>, selected: number})空白填充组件—Blank&#xff08;占位使用&#xff0c;当父组件为Row/Column/Flex时生效&am…

[SpringCloud] OpenFeign核心架构原理 (一)

Feign的本质: 动态代理 七大核心组件 Feign底层是基于JDK动态代理来的, Feign.builder()最终构造的是一个代理对象, Feign在构建对象的时候会解析方法上的注解和参数, 获取Http请求需要用到基本参数以及和这些参数和方法参数的对应关系。然后发送Http请求, 获取响应, 再根据响…
最新文章