Spring Cloud:三【详细】

news2024/12/23 9:37:27

目录

Http客户端Feign

Feign的使用

Feign自定义配置

第一种方式

第二种方式

Feign的优化

Feign最佳实践方式

实现一

实现二


Http客户端Feign

RestTemplate缺点是,url不统一,编写困难,可读性差,参数复杂难以维护。

这时我们可以使用Feign来代替RestTemplate。

Feign是一个声明式的http客户端。

Feign的使用

1、引入依赖spring-cloud-starter-openfeign

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

2、在启动类上添加注解@EnableFeignClients

3、定义Feign接口

@FeignClient("user-server")
public interface UserClient {
    @GetMapping("/user/{id}")
    User findById(@PathVariable("id")Long id);
}

4、修改Service类中的代码

@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private userClient userClient;
    
    public Order queryOrderById(Long orderId){
        Order order = orderMapper.findById(orderId);
        Long userId = order.getUserId();
        User user = userClient.getById(userId);
        order.setUser(user);
        return order;
    }
}

访问地址发现可以正常调用其他模块的方法。

需要注意的是Feign内部也是实现了负载均衡。内部集成了Ribbon

Feign自定义配置

Feign可以使用自定义配置去覆盖原始默认配置。可以修改的配置如下图

通常我们只需要修改日志级别(默认为NONE,什么也不打印)

第一种方式

修改配置文件

feign:
  client:
    config:
      default: #defaule就是全局配置,如果是写具体服务名,则是针对某个微服务的配置
        loggerLevel: FULL

除了打印SQL语句还打印了其他信息

第二种方式

添加配置类

public class FeignClientConfiguration {
    @Bean
    public Logger.Level feignLogLevel(){
        return Logger.Level.BASIC;
    }
}

不需要添加配置注解。如果在启动类上添加如下信息,表示全局生效

@EnableFeignClients(defaultConfiguration = FeignClientConfiguration.class)

如果在Client类上添加如下信息,表示局部生效

@FeignClient(value = "user-server",configuration= FeignClientConfiguration.class)
public interface UserClient {
    @GetMapping("/user/{id}")
    User findById(@PathVariable("id")Long id);
}

Feign的优化

Feign的优化点在于更换默认使用的底层客户端实现,默认使用是URLConnection,它不支持连接池。

可以使用以下两种客户端实现

  • HttpClient:支持连接池
  • OKHttp:支持连接池

其次优化点在于日志打印,一般我们不需要打印任何多余的日志,日志级别采用NONE即可,在调试的时候可以选择BASIC。

更改底层客户端实现:

引入依赖,去配置文件中配置连接池

<dependency>
  <groupId>io.github.openfeign</groupId>
  <artifactId>feign-httpclient</artifactId>
</dependency>
feign:
  client:
    config:
      default: #defaule就是全局配置,如果是写具体服务名,则是针对某个微服务的配置
        loggerLevel: NONE
  httpclient:
    enabled: true # 引入依赖后,需要手动配置开启httpClient
    max-connections: 200 # 最大连接数
    max-connections-per-route: 50 # 每个路径最大连接数

Feign最佳实践方式

一:由于Client就是发送Http请求所以请求路径和Controller的完全一样,因此给Client和Controller定义统一接口,让Client和Controller去继承和实现这个接口。所有的方法都写在父类接口中。

二:将FeignClient抽取为独立模块,把接口有关的POJO和默认配置放入独立模块中,其他服务需要调用Client时直接引入依赖调用

缺点:当模块A只需要模块B中的一两个方法时,仍然需要将所有方法都引入模块A中。

实现一

首先创建一个模块里面定义API接口

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

在订单模块下引入feign-api模块,并编写Client类

<dependency>
  <groupId>com.zmt</groupId>
  <artifactId>feign-api</artifactId>
  <version>1.0</version>
</dependency>
@FeignClient("user-server")
public interface UserClient extends UserAPI {
}

在用户模块下引入fegin-api依赖并编写Controller类

@RestController
@RequestMapping("/user")
public class UserController implements UserAPI {

    @Autowired
    private UserService userService;

    @Override
    public User findById(Long id) {
        return null;
    }
}

缺点:耦合度高、父接口中的参数列表中的映射关系不会被继承

实现二

仍然是创建一个feign-api模块,将其他模块中的Client类移动到feign-api模块中,其次移动相关配置类与实体类

在订单模块中引入feign-api模块

        <dependency>
            <groupId>xxxxx</groupId>
            <artifactId>feign-api</artifactId>
            <version>1.0</version>
        </dependency>

将原来模块中文件导入修改为feign-api中的路径即可

但是有一个问题,在订单模块中无法注入UserClient对象,因为OrderApplication中无法扫描另一个模块中的包。为了解决这个问题,有两种方案,一种是在启动类上添加包扫描,另一种是在启动类上指定客户端字节码文件。

// 方法一
@EnableFeignClients(basePackages = "cn.itcast.feign.clients")
// 方法二(推荐)
@EnableFeignClients(clients = {UserClient.class})

启动观察:

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

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

相关文章

【计算机网络笔记】DNS报文格式

DNS 提供域名到主机IP地址的映射  域名服务的三大要素&#xff1a;  域&#xff08;Domain&#xff09;和域名(Domain name)&#xff1a; 域指由地 理位置或业务类型而联系在一起的一组计算机构 成。  主机&#xff1a;由域名来标识。域名是由字符和&#xff08;或&a…

刚刚:腾讯云3年轻量2核2G4M服务器优惠价格366元三年

腾讯云3年轻量2核2G4M服务器&#xff0c;2023双十一优惠价格366元三年&#xff0c;自带4M公网带宽&#xff0c;下载速度可达512KB/秒&#xff0c;300GB月流量&#xff0c;50GB SSD盘系统盘&#xff0c;腾讯云百科txybk.com分享腾讯云轻量2核2G4M服务器性能、优惠活动、购买条件…

雷电_安卓模拟器安装burpsuit_CA证书

雷电_安卓模拟器安装burpsuit_CA证书 文章目录 雷电_安卓模拟器安装burpsuit_CA证书雷电模拟器官网&#xff1a;https://www.ldmnq.com 安装burpsuit证书1 打开雷电模拟器右上角的winfi图标 -->点击齿轮2 修改网络3 选择高级 —》手动4 查看真实机IP的地址&#xff0c;选择虚…

超分辨率重建——SESR网络训练并推理测试(详细图文教程)

最近学了一个超轻量化的超分辨率重建网络SESR&#xff0c;效果还不错。 目录 一、 源码包二、 数据集的准备2.1 官网下载2.2 网盘下载 三、 训练环境配置四、训练4.1 修改配置参数4.2 导入数据集4.3 2倍超分网络训练4.3.1 训练SESR-M5网络4.3.2 训练SESR-M5网络4.3.3 训练SESR…

Kitex踩坑 [Error] KITEX: processing request error,i/o timeout

报错问题 2023/010/28 17:20:10.250768 default_server_handler.go:234: [Error] KITEX: processing request error, remoteService, remoteAddr127.0.0.1:65425, errordefault codec read failed: read tcp 127.0.0.1:8888->127.0.0.1:65425: i/o timeout 分析原因 Hert…

【刷题笔记10.28】Leetcode:使括号有效的最少添加

Leetcode&#xff1a;使括号有效的最少添加 上代码 方法一&#xff1a;使用Deque 双向队列 /*** 方法一&#xff1a;使用Deque 双向队列* param s* return*/public int minAddToMakeValid(String s) {//1、将括号字符串转换为char[] 字符数组char[] data s.toCharArray();//2…

SDK 资源

目录 资源的使用 带资源的.exe文件的编译方式 向窗口发送消息 菜单 加载菜单 菜单消息 图标 光标 快捷键 字符串 资源的使用 在VS2019中&#xff0c;点击视图下的其他窗口&#xff0c;资源视图&#xff0c;就可以看到本项目的所有资源 鼠标右键添加-资源&#xff0c…

数据特征工程 | 主成分分析(Python)

特征抽取(feature extraction)和特征选择(feature selection)不一样,特征抽取是从原特征集中推导出有用的信息构成新的特征集。特征选择是从原特征集中选择一部分子集作为训练特征。 特征抽取将数据集从一个特征空间投影到了一个更低维度的特征空间。 主成分分析(princ…

C++设计模式_16_Adapter 适配器

Adapter 适配器也是属于“接口隔离”模式&#xff0c;也是间接思想在某一个层面的应用。 文章目录 1. 动机( Motivation)2. 模式定义3. 结构 (Structure)4. Adapter 适配器的代码实现5. 要点总结6. 其他参考 1. 动机( Motivation) 在软件系统中&#xff0c;由于应用环境的变化…

python:使用Scikit-image对遥感影像进行傅里叶变换特征提取(fourier)

作者:CSDN @ _养乐多_ 在本博客中,我们将介绍如何使用Scikit-Image来进行傅里叶变换特征提取(fourier),并且提供一个示例代码,演示了如何在单波段遥感图像上应用这些方法。 傅里叶变换特征提取是一种数学工具,用于将图像中的细节、纹理和边缘信息以不同频率的方式呈现…

[SpringCloud] Nacos 简介

目录 一、Nacos&#xff0c;启动&#xff01; 1、安装 Nacos 2、运行 Nacos 3、Nacos 服务注册 二、Nacos 服务多级存储模型 1、服务跨集群分配 2、NacosRule 负载均衡&#xff08;优先本地&#xff09; 3、服务实例的权重设置 4、环境隔离 三、Nacos 注册中心细节分…

私有云:【2】AD域的安装

私有云&#xff1a;【2】AD域的安装 1、使用vmwork创建虚拟机2、启动配置虚拟机3、安装域服务4、配置域服务器 1、使用vmwork创建虚拟机 新建虚拟机 稍后安装操作系统 选择win2012&#xff0c;如下图 设置名称及路径 分配硬盘大小&#xff0c;默认60G即可 镜像选择win2012的is…

【数据结构】数组和字符串(九):稀疏矩阵的链接存储:十字链表的插入、查找、删除操作

文章目录 4.2.1 矩阵的数组表示4.2.2 特殊矩阵的压缩存储a. 对角矩阵的压缩存储b~c. 三角、对称矩阵的压缩存储d. 稀疏矩阵的压缩存储——三元组表4.2.3三元组表的转置、加法、乘法、操作4.2.4十字链表0. 十字链表的创建、遍历打印、销毁1. 插入2. 查找3. 删除4. 主函数5. 代码…

C++学习day--22 宏和结构体

1、宏 1.1 为什么要使用宏 1、提高代码的可读性和可维护性 2、避免函数调用&#xff0c;提高程序效率 1.2 什么是宏 它是一种预处理器指令&#xff0c;在预编译阶段将宏名替换为后面的替换体 。 1.3 宏的定义 由三部分组成&#xff1a; #define WIDTH 960 三个部分分别是&…

Python 作用域:局部作用域、全局作用域和使用 global 关键字

变量只在创建它的区域内可用。这被称为作用域。 局部作用域 在函数内部创建的变量属于该函数的局部作用域&#xff0c;并且只能在该函数内部使用。 示例&#xff1a;在函数内部创建的变量在该函数内部可用&#xff1a; def myfunc():x 300print(x)myfunc()函数内部的函数 …

C++——类和对象(中)(2)尚未完结

拷贝构造 概念 在现实生活中&#xff0c;可能存在一个与你一样的自己&#xff0c;我们称其为双胞胎。 那在创建对象时&#xff0c;可否创建一个与已存在对象一某一样的新对象呢? 拷贝构造函数: 只有单个形参&#xff0c;该形参是对本类类型对象的引用(一般常用const修饰)&…

模块化编程

1、函数单独写在一个文件中.c&#xff0c;然后声明也写在一个文件中.h,在mian.c中引用 2、安装目录下面的文件夹用<>,在自己文件夹目录下就是"" 3、创建自己的&#xff08;先把函数放在c文件&#xff0c;再创建头h文件&#xff09;

ruoyi-plus创建模块、自动生成代码

ruoyi-plus自动生成代码 1、创建模块 复制其他部分的resouce过来 修改yml文件 2 修改Nacos 2.1 修改数据库文件 复制其他数据库的链接 &#xff0c;改为自己新建的数据库名字 修改为自己要生成的数据库 新建数据库的yaml文件 3 重启docker的ruoyi-gen服务 docker re…

数据结构【DS】B树

m阶B树的核心特性: Q&#xff1a;根节点的子树数范围是多少&#xff1f;关键字数的范围是多少&#xff1f; A&#xff1a;根节点的子树数∈[2, m],关键字数∈[1, m-1]。 Q&#xff1a;其他结点的子树数范围是多少&#xff1f;关键字数范围是多少&#xff1f; Q&#xff1a;对任…

SSD1306 oled显示屏的驱动SPI接口

有IIC接口 和SPI接口 还有8080,6080接口等 arduino SPI接口 直接使用u8g2库实现 //U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI u8g2(U8G2_R0, /* clock*/ 13, /* data*/ 11, /* cs*/ 10, /* dc*/ 9, /* reset*/ 8); asrpro(SPI接口按下方修改&#xff0c;IIC接口官方有驱动&…