OpenFeign介绍以及使用

news2025/1/3 5:40:22

介绍

OpenFeign 是一个声明式的 Web 服务客户端,用于简化在 Java 应用中调用 HTTP API 的过程,在 Spring Cloud 体系里被广泛应用,它有以下关键特性:

  • 声明式调用:基于注解,开发人员只需定义接口并添加注解,就能轻松描述对远程服务的 HTTP 请求,无需手动编写大量重复的 HTTP 客户端代码,如使用@FeignClient注解来指定要调用的服务名称。
  • 集成与适配:它能与 Spring Cloud 的服务发现机制(如 Eureka、Consul 等)无缝集成,调用远程服务时,借助服务发现找到目标服务实例的实际网络地址,开发者不用关心服务实例的具体位置和动态变化。同时,OpenFeign 可以方便地整合 Ribbon 实现客户端负载均衡,自动在多个服务实例间分摊请求流量。
  • 可定制化:提供了丰富的编码器和解码器,支持多种数据格式的传输,例如 JSON、XML 等。此外,还允许自定义请求拦截器,可在请求发送前添加公共的请求头、鉴权信息,满足复杂业务场景下的定制需求。
  • 熔断降级:可以结合 Hystrix 等熔断器框架,当被调用的远程服务出现故障、响应超时等异常情况时,快速触发熔断机制,返回预设的兜底数据,避免级联故障,保障整个微服务系统的稳定性。

使用原因

在我的上一章博客中使用了Nacos对微服务实现了服务的注册以及发现:微服务-注册中心-Nacos,但是发现了一个问题,我们在编写远程调用其他微服务的使用需要很长很复杂的一段http代码,如下:

其实远程调用的几个关键点就是:请求方式、请求路径、请求参数、返回值类型,所以本章用OpenFeign来解决微服务之间的远程调用复杂性,提高开发效率。

OpenFeign使用

这个案例是对上一章微服务-注册中心-Nacos的实例进行改造

1.引入依赖

在CloudDemo2中引入如下依赖:

  <!--openFeign-->
  <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-openfeign</artifactId>
  </dependency>
  <!--负载均衡器-->
  <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-loadbalancer</artifactId>
  </dependency>

删除启动类上的如下代码:

@Bean
  public RestTemplate restTemplate() {
    return new RestTemplate();
  }

2.启用OpenFeign

接下来,我们在cloudDemo2的CloudDemo2Application启动类上添加注解,启动OpenFeign功能:

@SpringBootApplication
@EnableFeignClients//开启OpenFeign功能支持
public class CloudDemo2Application {
  public static void main(String[] args) {
    SpringApplication.run(CloudDemo2Application.class);
  }
}

3.编写OpenFeign客户端

在cloudDemo2中创建一个client包,然后在下面创建一个OpenFeign客户端:

package com.waitforme.clouddemo2.client;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.List;

@FeignClient("cloudDemo1") //cloudDemo1微服务模块中配置文件所配置的微服务名
public interface CloudDemo1Client {
  /*
    @FeignClient("cloudDemo1") :声明服务名称
    @GetMapping :声明请求方式
    @GetMapping("/cloudDemo1/list") :声明请求路径
    List<Object> :返回值类型
   */
  @GetMapping("/cloudDemo1/list")
  List<Object> demo1List();
}

编写完上面的代码后,OpenFeign就可以利用动态代理帮我们实现这个方法,并且向http://cloudDemo1/cloudDemo1/list发送一个GET请求,并自动将返回值处理为List<Object>

我们只需要直接调用这个方法,即可实现远程调用了。

4.使用OpenFeign

修改CloudDemo2ServiceImpl代码

package com.waitforme.clouddemo2.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.waitforme.clouddemo2.client.CloudDemo1Client;
import com.waitforme.clouddemo2.service.CloudDemo2Service;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@RequiredArgsConstructor//为必要的类成员变量生成构造函数
public class CloudDemo2ServiceImpl implements CloudDemo2Service {
  private final CloudDemo1Client client;

  @Override
  public List<Object> getDemo1List() {
    List<Object> list = client.demo1List();
    if (CollUtil.isEmpty(list)) {
      return null;
    }
    return list;
  }
}

对比修改前后的代码:

修改前,使用restTemplate:

修改后:

5.启动测试

 启动服务,并清空IDEA控制台

在浏览器访问cloudDemo2的getDemo1路径,并刷新看我们的控制台输出

刷新三次页面控制台对比,得出可以使用OpenFeign正常调用,使用的是轮询负载均衡策略

cloudDmoe1的服务实例1

 cloudDmoe1的服务实例2

连接池的使用

OpenFeign 使用连接池主要有以下几方面好处:

  1. 性能提升
    • 减少连接创建开销:在频繁发起 HTTP 请求的场景下,如果不使用连接池,每次请求都需要创建新的 TCP 连接。这个创建过程涉及 TCP 三次握手,会消耗额外的网络往返时间以及系统资源。而连接池能够复用已有的连接,避免了反复创建和销毁连接的开销,显著加快请求响应速度。
    • 并发处理更高效:面对高并发的请求,连接池预先创建并管理了一批连接,多个线程可以同时从池中获取连接发起请求,无需等待新连接的缓慢建立,使得系统能够更从容地应对突发流量,提升整体并发处理能力。
  2. 资源优化
    • 降低系统资源消耗:持续不断地创建新连接会占用大量的系统资源,包括内存、CPU 时间等。连接池通过复用有限数量的连接,将资源消耗维持在一个较低水平,尤其对于资源受限的容器化环境或者小型服务器,这有助于维持系统稳定运行,避免因资源耗尽而出现性能瓶颈甚至崩溃。
  3. 稳定性增强
    • 应对网络波动:网络环境往往存在不稳定因素,如短暂的网络抖动、临时的服务中断。连接池中的连接一旦建立,只要没有出现严重故障,就可以持续复用。当遇到轻微网络波动时,不用频繁重新建立连接,减少因网络异常导致请求失败的概率,增强服务调用的稳定性。
  4. 可配置性与管控
    • 灵活配置:连接池通常提供了丰富的配置参数,例如连接池的最大连接数、最小连接数、连接的空闲时长等。开发人员可以根据实际业务场景和服务器资源状况,精细调整这些参数,实现性能与资源消耗之间的最优平衡。
    • 监控与维护:借助连接池,还能够方便地对连接的使用状态进行监控,了解连接的活跃数量、空闲数量、等待获取连接的线程数等关键信息,以便及时发现潜在问题,并采取诸如清理空闲连接、动态调整连接池大小等维护措施。

 1.引入依赖

在cloudDemo2中引入:

<!--OK http 的依赖 -->
<dependency>
  <groupId>io.github.openfeign</groupId>
  <artifactId>feign-okhttp</artifactId>
</dependency>

2.开启连接池

修改cloudDemo2的yaml配置文件,添加:

feign:
  okhttp:
    enabled: true # 开启OKHttp功能

 OpenFeign进阶使用

思考:如果我们的cloudDemo3模块也要调用cloudDemo1的demo1List方法,也要在cloudDemo3上面写一个OpenFeign客户端吗?

所以我们可以把要与其他微服务进行交互的部分抽取出来,单独提成一个微服务来专门管理远程调用

1.抽取Feign客户端

创建一个远程调用的模块

在openFeignApi的pom.xml中导入依赖,并删除cloudDemo2中的如下两个依赖,因为我们已经把远程连接相关的都提到单独的微服务中了,cloudDemo2中也不需要这两个依赖了。

<dependencies>
        <!--open feign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- load balancer-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
    </dependencies>

 2.把cloudDemo2中的client包剪切到openFeignApi模块下

3.在cloudDemo2和cloudDemo3的pom.xml中引入openFeign-Api的依赖

<dependency>
    <groupId>com.waitforme</groupId>
    <artifactId>openFeign-Api</artifactId>
    <version>1.0</version>
</dependency>

4.启动测试

 报错?

原因分析:我们把cloudDemo2的feign客户端抽取到了一个独立的微服务中,所以找不到了

解决方案:

1.在cloudDemo2的启动类的EnableFeignClients上声明扫描的包

2.声明要用的FeignClient

最后在浏览器中分别用cloudDemo2和cloudDemo3来访问测试

 日志配置

因为我们把openFeign单独抽出来做了一个微服务,而OpenFeign只会在FeignClient所在包的日志级别为DEBUG时,才会输出日志。它的日志级别有:

  • NONE:不记录任何日志信息,这是默认值。

  • BASIC:仅记录请求的方法,URL以及响应状态码和执行时间

  • HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息

  • FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据。

Feign默认的日志级别就是NONE,所以默认我们看不到请求日志。

1.定义日志级别

在openFeign-Api下创建一个config包,并创建一个配置类

package com.waitforme.openFeignApi.config;

import feign.Logger;
import org.springframework.context.annotation.Bean;

public class DefaultFeignConfig {
  @Bean
  public Logger.Level feignLogLevel() {
    return Logger.Level.FULL;
  }
}

2.配置

让日志级别生效

方式1:

局部配置,在某个FeignClient上加上configuration属性

@FeignClient(value = "cloudDemo1", configuration = DefaultFeignConfig.class) //cloudDemo1微服务模块中配置文件所配置的微服务名

方式2:

全局配置,在启动类添加defaultConfiguration属性,使FeignClient生效

@EnableFeignClients(clients = {CloudDemo1Client.class}, defaultConfiguration = DefaultFeignConfig.class)

3.重启服务,刷新浏览器请求,测试

控制台日志输出格式:

11:16:15:063 DEBUG 2456 --- [nio-8082-exec-2] c.w.o.client.CloudDemo1Client            : [CloudDemo1Client#demo1List] ---> GET http://cloudDemo1/cloudDemo1/list HTTP/1.1
11:16:15:065 DEBUG 2456 --- [nio-8082-exec-2] c.w.o.client.CloudDemo1Client            : [CloudDemo1Client#demo1List] ---> END HTTP (0-byte body)
11:16:15:242 DEBUG 2456 --- [nio-8082-exec-2] c.w.o.client.CloudDemo1Client            : [CloudDemo1Client#demo1List] <--- HTTP/1.1 200  (176ms)
11:16:15:242 DEBUG 2456 --- [nio-8082-exec-2] c.w.o.client.CloudDemo1Client            : [CloudDemo1Client#demo1List] connection: keep-alive
11:16:15:242 DEBUG 2456 --- [nio-8082-exec-2] c.w.o.client.CloudDemo1Client            : [CloudDemo1Client#demo1List] content-type: application/json
11:16:15:242 DEBUG 2456 --- [nio-8082-exec-2] c.w.o.client.CloudDemo1Client            : [CloudDemo1Client#demo1List] date: Sun, 29 Dec 2024 03:16:15 GMT
11:16:15:242 DEBUG 2456 --- [nio-8082-exec-2] c.w.o.client.CloudDemo1Client            : [CloudDemo1Client#demo1List] keep-alive: timeout=60
11:16:15:242 DEBUG 2456 --- [nio-8082-exec-2] c.w.o.client.CloudDemo1Client            : [CloudDemo1Client#demo1List] transfer-encoding: chunked
11:16:15:242 DEBUG 2456 --- [nio-8082-exec-2] c.w.o.client.CloudDemo1Client            : [CloudDemo1Client#demo1List] 
11:16:15:243 DEBUG 2456 --- [nio-8082-exec-2] c.w.o.client.CloudDemo1Client            : [CloudDemo1Client#demo1List] ["你好","你好,nacos","你好,微服务"]
11:16:15:243 DEBUG 2456 --- [nio-8082-exec-2] c.w.o.client.CloudDemo1Client            : [CloudDemo1Client#demo1List] <--- END HTTP (48-byte body)

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

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

相关文章

李永乐线性代数:A可逆,AX=B相关推论和例题解题思路

例题1&#xff1a; 思路讲解&#xff1a; 这个 (A-2E)可逆,所以有P(A-2E) E&#xff0c; 也就是(A-2E)的逆矩阵是P&#xff1b; 那么PA (A-2E)的逆 * A B P(A-2E,A)(E,B) 所以就可以直接求出B&#xff0c;也就是(A-2E)的逆 * A 例题2&#xff1a; 思路讲解&#xff1a;…

【Compose multiplatform教程18】多平台资源的设置和配置

要正确配置项目以使用多平台资源&#xff0c;请执行以下操作&#xff1a; 添加库依赖项。 为每种资源创建必要的目录。 为限定资源创建其他目录&#xff08;例如&#xff0c;深色 UI 主题或本地化字符串的不同图像&#xff09;。 依赖项和目录设置 要访问多平台项目中的资源…

Doris的SQL原理解析

今天来介绍下Doris的SQL原理解析&#xff0c;主要从语法、解析、分析、执行等几个方面来介绍&#xff0c;可以帮助大家对Doris底层有个清晰的理解~ 一、Doris简介 Apache Doris是一个基于MPP架构的高性能、实时的分析型数据库&#xff0c;能够较好的满足报表分析、即席查询、…

Excel for Finance 07 `FV PV` 函数

Excel 的 FV 函数用于计算一笔投资在未来的价值&#xff0c;基于固定的利率和定期付款。这是一个金融函数&#xff0c;常用来分析储蓄计划、贷款、或投资的增长。 语法&#xff1a; FV(rate, nper, pmt, [pv], [type])参数说明&#xff1a; rate&#xff08;必需&#xff09;&…

【运维】部署Gitea

部署Gitea Gitea文档 系统&#xff1a;Ubuntu 20.04.6 LTS 步骤&#xff1a; 准备数据库 使用内置 SQLite&#xff0c;无需额外准备。 下载安装 下载最新版本的 Gitea 并安装&#xff1a; wget -O gitea https://dl.gitea.com/gitea/version/gitea-version-linux-amd64 chm…

Redis KEYS查询大批量数据替代方案(推荐SCAN 命令)

文章目录 前言KEYS命令问题背景替代方案1.使用 SCAN 命令2. 使用有序集合&#xff08;Sorted Set&#xff09;3. 使用哈希&#xff08;Hash&#xff09;4. 使用 Redis 模块&#xff08;如 RediSearch&#xff09; 总结 前言 在使用 Redis 时&#xff0c;KEYS 命令虽然简单直接…

Apache Doris 创始人:何为“现代化”的数据仓库?

在 12 月 14 日的 Doris Summit Asia 2024 上&#xff0c;Apache Doris 创始人 & PMC 成员马如悦在开场演讲中&#xff0c;围绕“现代化数据仓库”这一主题&#xff0c;指出 3.0 版本是 Apache Doris 研发路程中的重要里程碑&#xff0c;他将这一进展总结为“实时之路”、“…

3. 指针、数组

目录 一、指针和数组 &#x1f350; 数组名指向首地址 &#x1f34a; 例子 二、数组作为函数参数 &#x1f34b; 数组名作为函数参数&#xff0c;为什么必须传递数组大小&#xff1f; 三、指针和字符数组 &#x1f34c;怎么样存储一个string&#xff1f; &#x1f349…

upload-labs关卡记录14

让上传图片马&#xff0c;并且三种后缀都要上传成功才算成功&#xff1a; 先试试gif的吧&#xff1a; 可以上传&#xff0c;同理&#xff1a;查看源码 只检查了两个字节&#xff0c;我们直接修改一句话木马&#xff0c;先改后缀php为png&#xff0c;然后winhex修改头部就完了 …

前端(htmlcss)

前端页面 Web页面 PC端程序页面 移动端APP页面 ... HTML页面 HTML超文本标记页面 超文本&#xff1a;文本&#xff0c;声音&#xff0c;图片&#xff0c;视频&#xff0c;表格&#xff0c;链接 标记&#xff1a;由许多标签组成 HTML页面运行到浏览器上面 vscode便捷插件使用 vs…

HTML——16.相对路径

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title></title></head><body><a href"../../fj1/fj2/c.html" target"_blank">链接到c</a><!--相对路径&#xff1a;-->…

coturn docker 项目 搭建【一切正常】

业务需求&#xff1a;需要coturn这个服务 定制语音视频连线 请参考"小红的逃脱外星人追踪计划" coturn项目 本地测试连接服务 turnutils_stunclient -p 3478 127.0.0.1turnutils_stunclient -p 3478 -L 127.0.0.1 127.0.0.1telnet localhost 3478turnutils_uclient …

【回溯】LeetCode经典题目总结:组合、排列、子集、分割、N皇后、单词搜索

回溯 组合问题组合总和全排列子集分割回文串N皇后电话号码的字母组合单词搜索括号生成 组合问题 给定两个整数 n 和 k&#xff0c;返回 1 … n 中所有可能的 k 个数的组合。 示例: 输入: n 4, k 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ] 树形结构&#xff1…

Linux-frp_0.61.1内网穿透的配置和使用

下载frp frp官网 https://gofrp.org/zh-cn/docs/setup/ frp安装包下载地址 https://github.com/fatedier/frp/releases?page1 下载之后在服务器上 解压 tar -zxvf frp_0.61.1_linux_amd64.tar.gztar&#xff1a;一个用于压缩和解压缩的工具。-z&#xff1a;表示使用 gzi…

WEB攻防-通用漏洞-文件上传-js验证-MIME验证-user.ini-语言特征

目录 定义 1.前端验证 2.MIME验证 3.htaccess文件和.user. ini 4.对内容进行了过滤&#xff0c;做了内容检测 5.[ ]符号过滤 6.内容检测php [] {} ; 7.()也被过滤了 8.反引号也被过滤 9.文件头检测 定义 文件上传漏洞是指攻击者上传了一个可执行文件&#xff08;如木马…

Excel基础知识

一&#xff1a;数组 一行或者一列数据称为一维数组&#xff0c;多行多列称为二维数组&#xff0c;数组支持算术运算&#xff08;如加减乘除等&#xff09;。 行&#xff1a;{1,2,3,4} 数组中的每个值用逗号分隔列&#xff1a;{1;2;3;4} 数组中的每个值用分号分隔行列&#xf…

快速下载pytorch_geometric

注意&#xff1a;千万不要一上去就使用pip去安装&#xff01;&#xff01;&#xff01; 1.找到GitHub手动下载所需依赖: https://github.com/pyg-team/pytorch_geometric 进入网址后点击此处&#xff1a; 2.点击here进去后寻找自己的torch版本&#xff08;我的是torch2.1.2的…

数学建模 绘图 图表 可视化(2)

文章目录 前言柱形图条形图克利夫兰点图系列坡度图南丁格尔玫瑰图径向柱图极坐标图词云图总结参考资料 前言 承接上期 数学建模 绘图 图表 可视化&#xff08;1&#xff09;的总体描述&#xff0c;这期我们继续跟随《Python 数据可视化之美 专业图表绘制指南》步伐来学习其中l…

建造者模式 Builder Pattern

在创建一个对象的时候&#xff0c;构造器参数有点多&#xff0c;而且有些参数还是可选的&#xff0c;再者还有不少同类型的&#xff0c;那就更应该使用 builder 模式了。 使用 Builder 模式的初衷是 把易变性&#xff08;mutability&#xff09;移动到Builder类&#xff0c;而…

【Java】IO流练习

IO流练习 题干&#xff1a; 根据指定要求&#xff0c;完成电话记录、 注册、登录 注册 题干&#xff1a; 完成【注册】功能&#xff1a; 要求&#xff1a; 用户输入用户名、密码存入users.txt文件中 若users.txt文件不存在&#xff0c;创建该文件若users.txt文件存在 输入…