远程调用总结

server/2025/2/8 21:18:56/

远程调用的作用

  在原来的springboot项目中通常是通过调用业务层来实现一个功能。在微服务中由于我们将许多业务进行一个拆开,但是我们需要其他业务层的数据所以就需要通过发送请求的方式来获取数据

实现注册中心nacos(第一步)

我们基于Docker来部署Nacos的注册中心,首先我们要准备MySQL数据库表,用来存储Nacos的数据。由于是Docker部署,所以大家需要将资料中的SQL文件导入到你Docker中的MySQL容器中:

其中的nacos/custom.env文件中,有一个MYSQL_SERVICE_HOST也就是mysql地址,需要修改为你自己的虚拟机IP地址:

然后,将课前资料中的nacos目录上传至虚拟机的/root目录。

进入root目录,然后执行下面的docker命令:

docker run -d \
--name nacos \
--env-file ./nacos/custom.env \
-p 8848:8848 \
-p 9848:9848 \
-p 9849:9849 \
--restart=always \
nacos/nacos-server:v2.1.0-slim

值得注意的是:当我们电脑的ip地址改变的时候 需要通过将nacos从docker中进行移除,重新通过docker进行run,同时别忘忘记将nacos/custom.env中的ip进行修改

启动完成后,访问下面地址:http://192.168.150.101:8848/nacos/,注意将192.168.150.101替换为你自己的虚拟机IP地址。

首次访问会跳转到登录页,账号密码都是nacos

服务注册

将一个模块注册到nacos注册中心的步骤如下

1.引入依赖

2.配置nacos地址

添加依赖

在需要实现nacos的模块中的pom文件中添加一下依赖

<!--nacos 服务注册发现-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

 配置Nacos

在yml文件添加nacos的地址配置

spring:application:name: item-service # 服务名称cloud:nacos:server-addr: 192.168.150.101:8848 # nacos地址

然后我们访问 http:虚拟机地址:8848/nacos/

看是否可以登录进去,如果可以登录进去就代表成功

 服务发现

服务的消费者要去nacos订阅服务,这个过程就是服务发现,步骤如下:

  • 引入依赖

  • 配置Nacos地址

  • 发现并调用服务

引入依赖

服务发现除了要引入nacos依赖以外,由于还需要负载均衡,因此要引入SpringCloud提供的LoadBalancer依赖。

在消费者中模块中添加一下依赖

<!--nacos 服务注册发现-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

这样消费者还有生产者都全部确定

OpenFegin(第二步)

快速使用

引入依赖

服务的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>

 启用OpenFegin

接下来,我们在cart-serviceCartApplication启动类上添加注解,启动OpenFeign功能:

"@EnableFeignClients" 这个注解就是气筒OpenFegin服务的注解

package com.hmall.cart;import com.hmall.api.config.DefaultFeignConfig;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;@EnableFeignClients(basePackages = "com.hmall.api.client",defaultConfiguration = DefaultFeignConfig.class)
@MapperScan("com.hmall.cart.mapper")
@SpringBootApplication
public class CartApplication {public static void main(String[] args) {SpringApplication.run(CartApplication.class, args);}
}

编写OpenFeign客户端

cart-service(这个服务是一个例子)中,定义一个新的接口,编写Feign客户端(现在是在cart包中,后面需要将统一写在api模块中):

其中代码如下:

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> :返回值类型

在这里我们需要搞清楚消费者和生产者:

 我们是将item-service中的服务进行注册,也就是item-service是生产者
 cart-service是消费者

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

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

使用FeignClient

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

连接池

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

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

  • Apache HttpClient :支持连接池

  • OKHttp:支持连接池

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

引入依赖

cart-servicepom.xml中引入依赖(值得注意的是我们是在消费者这边引入依赖):

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

开启连接池

cart-serviceapplication.yml配置文件中开启Feign的连接池功能(值得注意的是我们也是在消费者这边开启连接池功能):

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

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

最佳实践(其就是将消费者client转移统一的模块)

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

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

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

如图:

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

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

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

  抽取Fegin客户端

在自己的父项目定义新的的moduie,命名为xxx-api (由于在黑马上学习的,所以名为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>

现在,任何微服务要调用item-service(原来的没有进行拆解的项目)中的接口,只需要引入hm-api模块依赖即可,无需自己编写Feign客户端了。

扫描包

接下来,我们在cart-service(消费者)pom.xml中引入hm-api模块:

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

在这里需要注意的是由于我们将client(装有可以远程调用的client放在api)所以在启动的时候回扫描不到,所以我们需要在消费者启动类的
@EnableFeignClients(basePackages = "com.hmall.api.client")
中加上client中的包 就是像上面那样。


http://www.ppmy.cn/server/166030.html

相关文章

工作流项目BPMN.JS_Question梳理

工作流项目 想了解如果候选人熟悉工作流技术、bpmn.js和Flowable工作流引擎&#xff0c;面试官会对哪些信息感兴趣。我需要分析这个问题&#xff0c;并给出一个全面而结构化的回答。 首先&#xff0c;用户可能希望了解作为前端面试官&#xff0c;应该关注候选人哪些方面的知识和…

蓝耘智算平台搭载DeepSeek R1模型:高效环境配置全攻略

声明&#xff1a;非广告&#xff0c;为用户体验文章 目录 引言 一、蓝耘智算平台的核心优势 二、DeepSeek R1模型简介 三、蓝耘平台部署DeepSeek R1的详细步骤 &#x1f343;1&#xff1a;注册与登录蓝耘智算平台 &#x1f343;2&#xff1a;通过应用市场选择模型 &…

Java 集合中的 `removeIf` 和 Stream API 的 `filter`

前言 在Java编程中&#xff0c;处理集合数据是一项常见的任务。为了更高效地过滤集合中的元素&#xff0c;Java 8引入了两种强大的方法&#xff1a;removeIf 和 Stream API 中的 filter 方法。 一、removeIf 方法 1. 工作原理 removeIf 是 Collection 接口中的一个默认方法&…

工厂模式+枚举类的json序列化+redisson的使用

目录 这里分享以下工厂模式反射IoC容器多态的妙用 场景引入 环境准备 代码实现 1.设置枚举类来规定有哪些学习方式 2.设置作业的实体对象 3.获取学习方式的接口 4.进行学习的动作&#xff0c;有出题和搜题 5.使用小猿搜题这种学习方式进行的两种学习动作学习&#xff…

VSCode使用总结

1、VSCode左边资源窗口字体大小设置 方法一&#xff08;使用&#xff0c;已成功&#xff09; 进入安装目录Microsoft VS Code\resources\app\out\vs\workbench(如果是下载的压缩包&#xff0c;解压后resources\app\out\vs\workbench) 打开文件 workbench.desktop.main.css 搜…

Android 系统的启动流程

第一步&#xff0c;当用户按下手机电源键时&#xff0c;首先会从 ROM 中预定义的地方加载引导程序 Boot Loader 到 ARM 中&#xff1b; ROM&#xff08;Ready-Only-Memory&#xff09;&#xff1a;只读存储器&#xff0c;只能读出无法写入&#xff0c;即便是切断电源数据也不会…

JDBC笔记

简介 JDBC简单执行过程&#xff1a; 总结Java提供接口&#xff1b;数据库厂商提供实现&#xff1b;程序员调用接口&#xff1b;接口调用实现类&#xff0c;连接操作数据库 JDBC的概念 JDBC是Java提供的一组独立于任何数据库管理系统的API。 java操作数据库 步骤&#xff1a…

一键掌握多平台短视频矩阵营销/源码部署

短视频矩阵系统的介绍与应用 随着数字化营销策略的不断演进&#xff0c;传统的短视频矩阵操作方法可能已显陈旧。为此&#xff0c;一款全新的短视频矩阵系统应运而生&#xff0c;它通过整合多个社交媒体账户、创建多样化的任务、运用先进的智能视频编辑工具、实现多平台内容的…