微服务--OpenFeign【重点】

ops/2024/10/19 10:06:39/

如果哪天 我们硬编码写的接口变了,只要写过该接口的 都要改,太麻烦了,

所以 就用 OpenFeign 来解决这个麻烦

了解:

SimpleClientHttpRequestFactoryHttpComponentsClientHttpRequestFactory

都是Spring框架中用于创建ClientHttpRequest实例的工厂类

区别在于 底层使用的HTTP客户端库以及提供的特性和性能 :

1、RestTemplate 默认使用的是:

SimpleClientHttpRequestFactory工厂类(它用的是 JDK内置的 HttpURLConnection 性能比较低 ) ,

若换成HttpClient 【我们用的也是这个】 ,只需要在工厂里面 new 一个工厂类HttpComponentsClientHttpRequestFactory

package com.***.config;import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;@Configuration
public class RestConfig {@Bean@LoadBalanced// RestTemplate 默认将一级目录作为主机名,// 加上@LoadBalanced 之后,就把以及目录作为服务名,通过该服务名能够抓取到该服务名下面的所有实例数据,就可以负载均衡了// @LoadBalanced 会将RestTemplate 请求的url中的一级目录作为服务名,然后去服务注册中心Nacos抓取对应的ip和端口// 替换成真正的ip和端口  http://nacos-a/api/a ==> http://192.168.21.43:8080/api/a ,然后再去调用对应的接口//http://nacos-a/api/apublic RestTemplate restTemplate(){RestTemplate restTemplate = new RestTemplate();// 使用 httpclient 作为底层的http请求 来实现HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();restTemplate.setRequestFactory(clientHttpRequestFactory);return restTemplate;}
}

Feign

Feign 可以帮助我们更快捷、优雅地调用HTTP API,目的是让编写HTTP接口的客户端变得更简洁和直接

在Spring Cloud中,使用Feign非常简单——创建一个接口,并在接口上添加一些注解,代码就完成了

OpenFeign

1、Spring Cloud Alibaba快速整合OpenFeign

① 引入依赖

<!-- openfeign 远程调用 -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

② 编写调用接口+@FeignClient注解

name: 是服务名称,这是服务发现系统(如 Eureka 或 Nacos)中注册的服务名称

③ 调用端 在启动类上 添加@EnableFeignClients注解

@EnableFeignClients: 启用 Feign 客户端的支持。

通过类路径扫描找到所有的 @FeignClient 注解接口,并将它们注册为 Bean

④ 发起调用,像调用本地方法一样调用远程服务

⑤ Feign 使用 @SpringQueryMap 来解决多参数传递问题

你最近遇到最棘手的问题是什么?(踩过的坑)【面试题】

之前我们很多请求 都是通过post请求的,但是我们用get请求的时候 都是单个参数 没有用对象,有一次我们在封装成对象的时候 遇到问题了。

解决:加了一个@SpringQueryMap注解 将会扫描 方法参数中的字段或属性,拼接到URL上

2、高级配置

Feign 提供了很多的扩展机制,让用户可以更加灵活的使用

(1) 日志配置

当遇到 Bug,如接口调用失败、参数没收到等问题,或看调用性能,

就需要配置 Feign 的日志,以此让 Feign 把请求信息输出来。

Feign 提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解 Feign 中 Http 请求的细节

即:对Feign接口的调用情况进行监控和输出

通过源码可以看到日志等级有 4 种,分别是:

  • NONE【性能最佳,适用于生产】:不记录任何日志(默认值)。
  • BASIC【适用于生产环境追踪问题】:仅记录请求方法、URL、响应状态代码以及执行时间。
  • HEADERS:记录BASIC级别的基础上,记录请求和响应的header。
  • FULL【比较适用于开发及测试环境定位问题】:记录请求和响应的header、body和元数据。

① 全局配置

注意:

此处配置@Configuration注解就会全局生效,(如果想指定某一个服务生效,就不能加这个注解@Configuration)

因为feign调试日志是debug级别输出, SpringBoot默认的日志级别是Info,所以feign的debug日志级别就不会输出,一定要结合 logging.level.com.beiyou = debug

@Configuration
public class FeignConfig
{@BeanLogger.Level feignLoggerLevel(){return Logger.Level.FULL;}
}

② 局部配置

局部配置,让调用的微服务生效,在@FeignClient 注解中指定使用的配置类

局部配置的时候 FeignConfig要去掉@Configuration注解

③ 在配置文件配置
logging.level.com.*** = debug
开启日志##配置feign 的日志级别
#-- default 全局配置
feign.client.config.default.loggerLevel=NONE
#-- nacos-a 具体服务名
feign.client.config.nacos-a.loggerLevel=FULL

(2)超时配置

若服务提供者的请求处理时间超过了请求处理的超时时间,则会报Read timed out错误,如下图所示:

① 全局配置

为了避免服务调用连接和处理时间超时,我们可以对feign的连接超时时间和请求处理超时时间进行配置。

通过 Options 可以配置连接超时时间和读取超时时间

@Configuration
public class FeignConfig {@Beanpublic Request.Options options() {return new Request.Options(10L, TimeUnit.SECONDS, 60L,TimeUnit.SECONDS,false);}
}

注:Options 的第一个参数是连接的超时时间(ms),默认值是2s;第二个参数是请求处理的超时时间(ms),默认值是5s

② 配置文件中配置
#全局配置
#这里 default 是一个特殊的客户端名称,用于表示全局配置,
#设置 connectTimeout 和 readTimeout 属性的值来定义全局的连接超时时间和读取超时时间。feign.client.config.default.connectTimeout=5000
feign.client.config.default.readTimeout=10000#局部配置 请将 <clientName> 替换为实际的Feign客户端名称。
feign.client.config.<clientName>.connectTimeout=5000
feign.client.config.<clientName>.readTimeout=10000feign.client.config.order-service.connectTimeout=5000    #连接超时时间(ms),默认值是2s
feign.client.config.order-service.readTimeout=10000      #请求处理的超时时间(ms),默认值是5s

补充说明: Feign的底层用的是Ribbon,但超时时间以Feign配置为准

(3)自定义拦截器(重要 重要 重要.......)

通过在OpenFeign中自定义拦截器的方式,来实现服务远程调用过程中的日志输出、认证授权等应用

  • OpenFeign 中的拦截器是对服务调用者(也叫消费者)调用服务提供者的过程进行拦截。
  • Spring MVC 中的拦截器是对客户端(浏览器)请求服务端的过程进行拦截。

通过输出日志的例子来介绍OpenFeign中拦截器的使用步骤

① 自定义OpenFeign拦截器类

在服务消费者项目中创建一个名称为TraceIdFeignInterceptor 的拦截器类,并让其继承RequestInterceptor类。

@Slf4j
//@Component
public class TraceIdFeignInterceptor implements RequestInterceptor {@Overridepublic void apply(RequestTemplate template) {log.debug("请求拦截了");}
}

② 配置拦截器
方式一: 全局配置 (在配置类中配置自定义的OpenFeign拦截器)
@Configuration
public class FeignConfig {@Beanpublic TraceIdFeignInterceptor feignInterceptor(){return new TraceIdFeignInterceptor ();}
}

方式二: 局部配置 (也可以在application.yaml文件中对自定义的OpenFeign拦截器进行局部配置)
# 拦截器
feign.client.config.order-service.requestInterceptors[0]=com.beiyou.TraceIdFeignInterceptor #自定义拦截器的完整类路径
feign.client.config.order-service.requestInterceptors[1]=com.beiyou.xxxxxxxxx

方式三: 常用简化版

传两个 因为这两个都是要一直链路传的,从第一个服务 一直传到尾

traceId 主要解决 链路跟踪问题

token 主要验证前端给我们的token是否合法,有一些接口需要拿token里面用户的信息 所以要一直传到下游

使用openfeign 调用另一个微服务的get方法,如果参数是 对象的话,需要添加 @SpringQueryMap 注解

了解:契约配置

Spring Cloud 在 Feign 的基础上做了扩展,使用 Spring MVC 的注解来完成Feign的功能。原生的 Feign 是不支持 Spring MVC 注解的,如果你想在 Spring Cloud 中使用原生的注解方式来定义客户端也是可以的,通过配置契约来改变这个配置,Spring Cloud 中默认的是 SpringMvcContract。

Spring Cloud 1 早期版本就是用的原生Fegin. 随着netflix的停更替换成了Open feign

1)修改契约配置,支持Feign原生的注解

注意:修改契约配置后,OrderFeignService 不再支持springmvc的注解,需要使用Feign原生的注解

/*** 修改契约配置,支持Feign原生的注解*/
@Bean
public Contract feignContract() {return new Contract.Default();
}

2)OrderService 中配置使用Feign原生的注解

@FeignClient(value = "order-service")
public interface OrderService {@RequestLine("GET /hello")public String hello();
}

3)也可以通过yml配置契约

feign:client:config:order-service:  #对应微服务loggerLevel: FULLcontract: feign.Contract.Default   #指定Feign原生注解契约配置

http://www.ppmy.cn/ops/126690.html

相关文章

Midjourney中文版:创意无界,绘梦成真

在数字艺术的浩瀚宇宙中&#xff0c;Midjourney中文版如同一颗璀璨的新星&#xff0c;以其独特的魅力和无限可能&#xff0c;引领着每一位创作者探索创意的无限边界。作为专为国内用户打造的AI绘画工具&#xff0c;Midjourney中文版不仅继承了原版的核心优势&#xff0c;更在本…

如何解决 Windows PowerShell 中 “无法加载文件 pnpm.ps1” 的错误

搜索 PowerShell&#xff0c;以管理员身份运行 在终端输入 get-ExecutionPolicy 查看执行策略/权限&#xff1b; 此时应该是输出&#xff1a;Restricted(受限制的)&#xff1b; 然后在终端输入set-ExecutionPolicy -Scope CurrentUser 命令给用户赋予权限&#xff1b; 输入&am…

飞机大战告尾

参考 PPO算法逐行代码详解 链接 通过网盘分享的文件&#xff1a;PlaneWar 链接: https://pan.baidu.com/s/1cbLKTcBxL6Aem3WkyDtPzg?pwd1234 提取码: 1234 10.17关于博客发了又改这件事 悲催的事 今天训练了一早上ppo模型&#xff0c;满怀期待的检测成果时发现一点长进都…

推荐算法的学习

文章目录 前言1、模型1.1 从本领域模型的发展历史中学习1.1.1 在历史中总结发展规律和趋势1.1.2 发现模型之间的共性&#xff0c;方便记忆 1.2 从其他领域的发展中学习1.2.1 注意力机制1.2.2 残差网络 1.3 实践该怎么办&#xff1f; 2、 特征2.1 数据源的选择与建立2.2 特征构造…

【java面经thinking】一

目录 类加载过程 加载&#xff1a; 连接 初始化 GC回收机制&#xff08;垃圾回收&#xff09; 区域 判断对象是否存活 回收机制 HashMap 类加载器 加载标识 加载机制 缓存 自定义加载器&#xff1a; JVM内存结构 常量池 string设置成final 按下网址发生 类加…

59.螺旋矩阵②

目录 题目解法解决方案的关键点&#xff1a;代码实现&#xff1a;代码解释&#xff1a;输出结果&#xff1a;复杂度分析&#xff1a; 如何创建一个纯1的矩阵&#xff1f;奇偶矩阵的边界在何处做限制if (top < bottom)为什么要有这个限制&#xff1f; 不一定需要先把num数组做…

Java项目-基于Springboot的在线外卖系统项目(源码+说明).zip

作者&#xff1a;计算机学长阿伟 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、ElementUI等&#xff0c;“文末源码”。 开发运行环境 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBoot、Vue、Mybaits Plus、ELementUI工具&#xff1a;IDEA/…

子网掩码问题3 已知ip 地址数是5

假设 1.1.1.0 /24 需 划分27 个地址&#xff0c;求这个地址段的网络位&#xff0c;主机位&#xff0c;以及他们的详细信息 解&#xff1a; 假设主机地址位数是x 那么主机的地址个数 2的x次方-2 因为地址不能全部为0 也不能全为1 2 的x 次方 -2 > 27…