微服务-01【续】

news2024/12/13 17:32:14

1.OpenFeign

上篇文章我们利用Nacos实现了服务的治理,利用利用RestTemplate实现了服务的远程调用。但是远程调用的代码太复杂了:

而且这种调用方式,与原本的本地方法调用差异太大,编程时的体验也不统一,一会儿远程调用,一会儿本地调用。因此,我们必须想办法改变远程调用的开发模式,让远程调用像本地方法调用一样简单。而这就要用到OpenFeign组件了。

其实远程调用的关键点就在于四个:

  • 请求方式

  • 请求路径

  • 请求参数

  • 返回值类型

所以,OpenFeign就利用SpringMVC的相关注解来声明上述4个参数,然后基于动态代理帮我们生成远程调用的代码,而无需我们手动再编写,非常方便。

1.1 快速入门

还是以cart-service中的查询我的购物车为例。因此下面的操作都是在cart-service中进行。

1.1.1 引入依赖

cart-service服务的pom.xml中引入OpenFeign的依赖和loadBalancer依赖:

  <!--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>
1.2 启动OpenFeign

cart-serviceCartApplication启动类上添加注解,启动OpenFeign功能:

1.3 编写OpenFeign客户端

cart-service中,定义一个新的接口:

package com.hmall.cart.client;

import com.hmall.cart.domain.dto.ItemDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;

@FeignClient("item-service")
public interface ItemClient {

    @GetMapping("/items")
    List<ItemDTO> queryItemByIds(@RequestParam("ids") Collection<Long> ids);
}

 这里只需要声明接口,无需实现方法。接口中的几个关键信息:

  • @FeignClient("item-service") :声明服务名称

  • @GetMapping :声明请求方式

  • @GetMapping("/items") :声明请求路径

  • @RequestParam("ids") Collection<Long> ids :声明请求参数

  • List<ItemDTO> :返回值类型

有了上述信息,OpenFeign就可以利用动态代理帮我们实现这个方法,并且向http://item-service/items发送一个GET请求,携带ids为请求参数,并自动将返回值处理为List<ItemDTO>。我们只需要直接调用这个方法,即可实现远程调用了。

1.4 使用FeignClient

最后,我们在cart-servicecom.hmall.cart.service.impl.CartServiceImpl中改造代码,直接调用ItemClient的方法:

feign替我们完成了服务拉取、负载均衡、发送http请求的所有工作。 

2. 连接池

Feign底层发起http请求,依赖于其它的框架。其底层支持的http客户端实现包括:

  • HttpURLConnection:默认实现,不支持连接池

  • Apache HttpClient :支持连接池

  • OKHttp:支持连接池

因此我们通常会使用带有连接池的客户端来代替默认的HttpURLConnection。比如,我们使用OK Http.

2.1 引入依赖

cart-servicepom.xml中引入依赖:

<!--OK http 的依赖 -->
<dependency>
  <groupId>io.github.openfeign</groupId>
  <artifactId>feign-okhttp</artifactId>
</dependency>
2.2 开启连接池

cart-serviceapplication.yml配置文件中开启Feign的连接池功能:

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

重启服务,连接池就生效了。

2.3 最佳实践

其他微服务,也可能需要远程调用item-service中根据id批量查询商品功能。这个需求与cart-service中是一样的。因此,我们就需要在trade-service中再次定义ItemClient接口,这不是重复编码吗? 有什么办法能加避免重复编码呢?

2.3.1 思路分析

相信大家都能想到,避免重复编码的办法就是抽取。不过这里有两种抽取思路:

  • 思路1:抽取到微服务之外的公共module

  • 思路2:每个微服务自己抽取一个module

如图:

方案1抽取更加简单,工程结构也比较清晰,但缺点是整个项目耦合度偏高。

方案2抽取相对麻烦,工程结构相对更复杂,但服务之间耦合度降低。

由于item-service已经创建好,无法继续拆分,因此这里我们采用方案1.

2.3.2 抽取Feign客户端

hmall下定义一个新的module,命名为hm-api

 依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>hmall</artifactId>
        <groupId>com.heima</groupId>
        <version>1.0.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>hm-api</artifactId>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <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>
        <!-- swagger 注解依赖 -->
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>1.6.6</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</project>

然后把ItemDTO和ItemClient都拷贝过来,最终结构如下:

 2.3.3 扫描包

cart-servicepom.xml中引入hm-api模块:

  <!--feign模块-->
  <dependency>
      <groupId>com.heima</groupId>
      <artifactId>hm-api</artifactId>
      <version>1.0.0</version>
  </dependency>

删除cart-service中原来的ItemDTO和ItemClient,重启项目,发现报错了:

这里因为ItemClient现在定义到了com.hmall.api.client包下,而cart-service的启动类定义在com.hmall.cart包下,扫描不到ItemClient,所以报错了。

解决办法很简单,在cart-service的启动类上添加声明即可,两种方式:

  • 方式1:声明扫描包:

  • 方式2:声明要用的FeignClient

 2.4 日志配置

OpenFeign只会在FeignClient所在包的日志级别为DEBUG时,才会输出日志。而且其日志级别有4级:

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

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

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

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

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

定义日志级别:

在hm-api模块下新建一个配置类,定义Feign的日志级别:

让日志级别生效,还需要配置这个类。有两种方式:

  • 局部生效:在某个FeignClient中配置,只对当前FeignClient生效

@FeignClient(value = "item-service", configuration = DefaultFeignConfig.class)
  • 全局生效:在@EnableFeignClients中配置,针对所有FeignClient生效。

@EnableFeignClients(defaultConfiguration = DefaultFeignConfig.class)

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

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

相关文章

中电金信携手中远海科,共启贸易金融数智新篇章

在数智化转型成为驱动经济社会高质量发展的新引擎背景下&#xff0c;“数智方案”栏目聚焦金融等国计民生重点行业场景&#xff0c;依托中电金信“源启筑基咨询引领应用重构”的产品及服务体系&#xff0c;输出市场洞察和行业解决方案、应用案例&#xff0c;旨在全面推动行业IT…

【前端】React快速构建登陆注册前后端全栈

近期更新完毕&#xff0c;建议关注、收藏&#xff01; 目录 快速入门 快速入门 前提&#xff1a;安装npm #npm install react react-dom conda install nodejs npm install create-react-app cd my-app#切换到项目文件夹 npm install npm i web-vitals --save-dev #如果上述…

JS中的原型链与继承

文章目录 原型链的类比原型链对像与函数拥有的原型属性不同原型链的产生对象的constructor属性继承 原型链的类比 JS中原型链&#xff0c;本质上就是对象之间的关系&#xff0c;通过protoype和[[Prototype]]属性建立起来的连接。这种链条是动态的&#xff0c;可以随时变更。 …

Ubuntu22.04搭建FTP服务器保姆级教程

在网络环境中&#xff0c;文件传输是一项至关重要的任务。FTP&#xff08;文件传输协议&#xff09;是一种基于客户端/服务器模式的协议&#xff0c;广泛用于在互联网上传输文件。Ubuntu作为一款流行的Linux发行版&#xff0c;因其稳定性和易用性而广受开发者和系统管理员的喜爱…

基于Kubesphere实现微服务的CI/CD——部署微服务项目(三)

目录 一、kubesphere安装 1、安装本地持久存储 1.1、default-storage-class.yaml 1.2、 openebs-operator.yaml 1.3、安装 Default StorageClass 2、安装kubesphere 2.1、安装Helm 2.2、安装kubesphere 二、配置kubesphere 1、安装插件 2、创建devops项目 3、配置…

jenkins harbor安装

Harbor是一个企业级Docker镜像仓库‌。 文章目录 1. 什么是Docker私有仓库2. Docker有哪些私有仓库3. Harbor简介4. Harbor安装 1. 什么是Docker私有仓库 Docker私有仓库是用于存储和管理Docker镜像的私有存储库。Docker默认会有一个公共的仓库Docker Hub&#xff0c;而与Dock…

open cv学习之图片矫正

一&#xff0c;实验原理 图像矫正的原理是透视变换 图像畸变主要有两类&#xff1a;径向畸变和切向畸变。径向畸变通常会导致图像的四个角向外或向内弯曲&#xff1b;切向畸变则是由于相机与图像平面不完全平行引起的。而OpenCV 提供了一个相机标定的工具&#xff0c;能够自动…

【再谈设计模式】组合模式~层次构建的多面手

一、引言 在软件开发的世界里&#xff0c;我们经常面临着处理对象之间复杂关系的挑战。如何有效地表示对象的部分 - 整体层次结构&#xff0c;并且能够以一种统一的方式操作这些对象&#xff0c;是一个值得探讨的问题。组合模式&#xff08;Composite Pattern&#xff09;为我们…

关于Git分支合并,跨仓库合并方式

关于Git合并代码的方式说明 文章目录 关于Git合并代码的方式说明前情提要开始合并方式一&#xff1a;git merge方式二&#xff1a;git cherry-pick方式三&#xff1a;git checkout Git跨仓库合并的准备事项前提拉取源仓库代码 前情提要 同仓库不同分支代码的合并可直接往下看文…

Android Freezer

Freezer原理 Android按照优先级将一般的APP从高到低分为: 前台进程 --> 可感知进程–> 服务进程 --> Cached进程。 Freezer通过冻住cached进程,来迫使这些进程让出CPU&#xff0c;以达到优化系统资源使用的目的。 Cached进程是怎么判定的呢&#xff1f; 由于andro…

websocker的java集成过程

第一步&#xff1a;引入依赖包 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dependency> 第二步设置配置类&#xff1a; // 需要注入Bean的话必须声明为配置类 Co…

设计模式:24、访问者模式

目录 0、定义 1、访问者模式的五种角色 2、访问者模式的UML类图 3、示例代码 0、定义 表示一个作用于某对象结构中的各个元素的操作。它可以在不改变各个元素的类的前提下&#xff0c;定义作用于这些元素的新操作。 1、访问者模式的五种角色 抽象元素&#xff08;Element…

umi实现动态获取菜单权限

文章目录 前景登录组件编写登录逻辑菜单的时机动态路由页面刷新手动修改地址 前景 不同用户拥有不同的菜单权限&#xff0c;现在我们实现登录动态获取权限菜单。 登录组件编写 //当我们需要使用dva的dispatch函数时&#xff0c;除了通过connect函数包裹组件还可以使用这种方…

Color-Light-Control-and-Four-Way-Responder based on STM32F103C8T6

Light Control and Responder 若要实现同样效果请看源码: gitee.com/apollo_666/Color-Light-Control-and-Four-Way-Responder # Abstract The design project for a decorative lighting controller enhanced our practical skills and engineering capabilities. During our…

数据库中的运算符

1.算术运算符 算术运算符主要用于数学运算&#xff0c;其可以连接运算符前后的两个数值或表达式&#xff0c;对数值或表达式进行加&#xff08;&#xff09;、减&#xff08;-&#xff09;、乘&#xff08;*&#xff09;、除&#xff08;/&#xff09;和取模&#xff08;%&…

python爬虫--小白篇【爬取B站视频】

目录 一、任务分析 二、网页分析 三、任务实现 一、任务分析 将B站视频爬取并保存到本地&#xff0c;经过分析可知可以分为四个步骤&#xff0c;分别是&#xff1a; 爬取视频页的网页源代码&#xff1b;提取视频和音频的播放地址&#xff1b;下载并保存视频和音频&#x…

【计算机网络】实验18:动态主机配置协议DHCP的作用

实验18 动态主机配置协议DHCP的作用 一、实验目的 验证动态主机协议DHCP的作用 二、实验环境 Cisco Packet Tracer模拟器 三、实验过程 1.构建网络拓扑&#xff0c;不给局域网中的各主机手动配置IP地址、子网掩码、默认网关、DNS服务器等信息&#xff0c;而是开启动态主机…

MFC案例:基于对话框的简易阅读器

一、功能目标&#xff1a; 1.阅读txt文件 2.阅读时可以调整字体及字的大小 3.打开曾经阅读过的文件时&#xff0c;能够自动从上次阅读结束的位置开始显示&#xff0c;也就是能够保存和再次使用阅读信息。 4.对于利用剪贴板粘贴来的文字能够存储成txt文件保存。 5.显示…

【开源】基于SpringBoot框架的个性化的旅游网站 (计算机毕业设计)+万字毕业论文 T025

系统合集跳转 源码获取链接 一、系统环境 运行环境: 最好是java jdk 1.8&#xff0c;我们在这个平台上运行的。其他版本理论上也可以。 IDE环境&#xff1a; Eclipse,Myeclipse,IDEA或者Spring Tool Suite都可以 tomcat环境&#xff1a; Tomcat 7.x,8.x,9.x版本均可 操作系统…

谷粒商城—分布式基础

1. 整体介绍 1)安装vagrant 2)安装Centos7 $ vagrant init centos/7 A `Vagrantfile` has been placed in this directory. You are now ready to `vagrant up` your first virtual environment! Please read the comments in the Vagrantfile as well as documentation on…