微服务——远程调用

news/2024/9/19 1:10:06/ 标签: 微服务, 架构

为什么需要远程调用?

        在微服务架构中,每个服务都是独立部署和运行的,它们之间需要相互协作以完成复杂的业务逻辑。因此,远程调用成为微服务之间通信的主要方式。通过远程调用,一个服务可以请求另一个服务执行某些操作或获取所需数据,从而实现服务的解耦和复用。

        例如:在商城项目拆分中购物车业务中需要查询商品信息,但商品信息查询的逻辑全部迁移到了item-service服务,导致我们无法查询。最终结果就是查询到的购物车数据不完整,因此要想解决这个问题,我们就必须改造其中的代码,把原本本地方法调用,改造成跨微服务的远程调用(RPC,即Remote Produce Call)。

查询购物车列表的流程图:

远程调用的方式

微服务远程调用的方式多种多样,主要包括以下几种:

  1. HTTP/REST
    • 使用HTTP协议进行同步调用,通常使用JSON或XML作为数据交换格式。
    • 优点:简单、通用性强、可跨语言、跨平台。
    • 缺点:消息封装较为臃肿,对于大量数据或频繁调用的场景可能不是最优选择。
  2. RPC(远程过程调用)
    • 允许像调用本地方法一样调用远程服务的方法。
    • 优点:通信速度快、效率高、可自定义数据格式。
    • 缺点:限制于开发语言环境,跨语言和跨平台能力较弱。
  3. 消息队列
    • 通过消息队列进行消息传递,实现服务之间的解耦。
    • 优点:高可用性、高可扩展性、低耦合性。
    • 缺点:实时性较弱,可能不适用于所有场景。
  4. 事件总线
    • 发布/订阅模型,通过事件进行通信。
    • 优点:解耦程度高、灵活性好。
    • 缺点:实现复杂度较高,需要维护事件的定义和订阅关系。

远程调用的实现框架

微服务架构中,有多种框架支持远程调用,以下是一些常见的实现框架:

  1. RestTemplate
    • Spring 提供的用于访问 Rest 服务的客户端。
    • 提供了多种便捷访问远程 HTTP 服务的方法。
    • 示例代码:通过配置类注入 RestTemplate Bean,并在 Controller 中使用它发送 HTTP 请求。
  2. Feign
    • Netflix 开发的声明式、模板化的 Http 客户端。
    • 通过处理注解相关信息生成 Request,并对调用返回的数据进行解码。
    • OpenFeign 是 Spring Cloud 在 Feign 的基础上增加了对 SpringMVC 注解的支持。
    • 示例代码:定义 Feign 客户端接口,使用 @FeignClient 注解指定要调用的服务,并在接口方法上使用 SpringMVC 注解定义请求路径和参数。
  3. gRPC
    • Google 开源的高性能、跨语言的 RPC 框架。
    • 使用 Protocol Buffers 作为接口描述语言。
    • 适用于对性能要求较高的场景。
  4. Dubbo
    • 阿里巴巴开源的 Java RPC 框架。
    • 支持多种序列化方式,适用于 Java 微服务架构

我们以RestTemplate为例,RestTemplate其中提供了大量的方法,方便我们发送Http请求,例如:

可以看到常见的Get、Post、Put、Delete请求都支持,如果请求参数比较复杂,还可以使用exchange方法来构造请求。

我们在服务中定义一个配置类:

先将RestTemplate注册为一个Bean:(首先需要去声明request method)

package com.hmall.cart.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;@Configuration
public class RemoteCallConfig {@Beanpublic RestTemplate restTemplate() {return new RestTemplate();}
}

接下来,我们修改service中的服务实现类中方法,发送http请求到service

可以看到,利用RestTemplate发送http请求与前端ajax发送请求非常相似,都包含四部分信息:

  • ① 请求方式(master枚举:get、post等)

  • ② 请求路径(请求的URL路径里面包含的首先就是请求的IP,然后是请求端口,最后才是真正的资源路径)

  • ③ 请求参数(查询默认情况下服务端返回都是JASON格式的,但是Rest template可以帮你转成你想要的java类型。比如查到的是个user,那就可以写成user.class。它就会返回一个user,会把你查到的JASON的字符串反序列化)

  • ④ 返回值类型(请求中如果有参数,比如说有路径占位符参数,可以使用map指定这个参数
    map里面要指定一个key和value,key要跟占位符一致,value就是你的具体的参数)

在实现类中使用Rest template

最常规的方法是autowear注入

        但是这种方式spring是不推荐的,它推荐采用构造函数注入,写一个构造函数spring也能帮你做自动注入。

但是假如成员变量很多,那构造函数的列表就会非常长。所以使用lombok可以帮助我们去自动生成构造函数。

什么是lombok库?

        Lombok是一个Java库,它可以帮助开发者自动生成getter和setter方法、构造函数、equals、hashCode和toString方法等,从而减少样板代码,提高开发效率。

  1. @AllArgsConstructor:这个注解会为类生成一个包含所有参数的构造函数。如果不希望某个变量成为构造函数的一部分,那么不应该使用这个注解。

  2. @RequiredArgsConstructor:这个注解会为需要特殊处理的字段(如final字段和被@NonNull注解的字段)生成一个构造函数。这样,只有这些“必需”的字段才会被包含在构造函数中。

  3. final字段:如果将某个字段声明为final,那么它必须在声明时或在构造函数中进行初始化。使用@RequiredArgsConstructor注解时,Lombok会自动为这些final字段生成一个构造函数,以确保它们被正确初始化。

  4. 手动初始化:如果已经在字段声明时对其进行了初始化,那么即使使用了@AllArgsConstructor@RequiredArgsConstructor注解,该字段也不会被包含在自动生成的构造函数中,因为它已经被初始化了。

实现类的方法的完整代码如下:

private void handleCartItems(List<CartVO> vos) {// TODO 1.获取商品idSet<Long> itemIds = vos.stream().map(CartVO::getItemId).collect(Collectors.toSet());// 2.查询商品// List<ItemDTO> items = itemService.queryItemByIds(itemIds);// 2.1.利用RestTemplate发起http请求,得到http的响应ResponseEntity<List<ItemDTO>> response = restTemplate.exchange("http://localhost:8081/items?ids={ids}",HttpMethod.GET,null,new ParameterizedTypeReference<List<ItemDTO>>() {},Map.of("ids", CollUtil.join(itemIds, ",")));// 2.2.解析响应if(!response.getStatusCode().is2xxSuccessful()){// 查询失败,直接结束return;}List<ItemDTO> items = response.getBody();if (CollUtils.isEmpty(items)) {return;}// 3.转为 id 到 item的mapMap<Long, ItemDTO> itemMap = items.stream().collect(Collectors.toMap(ItemDTO::getId, Function.identity()));// 4.写入vofor (CartVO v : vos) {ItemDTO item = itemMap.get(v.getItemId());if (item == null) {continue;}v.setNewPrice(item.getPrice());v.setStatus(item.getStatus());v.setStock(item.getStock());}
}

http://www.ppmy.cn/news/1516787.html

相关文章

【Python机器学习】NLP概述——词序和语法

词的顺序很重要&#xff0c;那些在词序列&#xff08;如句子&#xff09;中控制词序的规则被称为语言的语法&#xff08;也被称为文法&#xff09;。这是之前的词袋或词向量例子中所丢弃的信息。在大多数简短的短语甚至许多完整的句子中&#xff0c;上述词向量近似方法都可以奏…

设计模式 7 桥接模式

设计模式 7 创建型模式&#xff08;5&#xff09;&#xff1a;工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式结构型模式&#xff08;7&#xff09;&#xff1a;适配器模式、桥接模式、组合模式、装饰者模式、外观模式、享元模式、代理模式行为型模式&#xff0…

整合sentinel遇到的小问题

1.运行jar包 &#xff0c;端口为默认8080 正确命令 java -Dserver.port8090 -Dcsp.sentinel.dashboard.server127.0.0.1:8090 -Dproject.namesentinel-dashboard -jar sentinel-dashboard-1.8.6.jar -D这些指令要在 -jar前面 在宝塔部署时&#xff0c;直接复制到运行命令后…

vue事件监听

我们可以使用 v-on 指令 (简写为 ) 来监听 DOM 事件&#xff0c;并在事件触发时执行对应的 1.回车事件&#xff08;点击回车触发&#xff09; confirm 适用uni-app keyup.enter 适用vue3 运用场景&#xff1a;通常在文本框输入的时候使用 2.点击事件&#xff08;鼠标左键…

Cubase操作:如何修改每个音频块的名字 写歌习惯

如何修改每个音频块的名字 我对命名比较注重&#xff0c;之前用Cubase12&#xff0c;导入我手机中编辑过的Cubasis的工程时&#xff0c;发现中文部分有乱码…… 而且好像改名改得很费劲…… 后面通过多方咨询和探索思考&#xff0c;终于找到方法了&#xff01; 可以先把信息…

【C#】【EXCEL】BumblebeeComponentsAnalysisGH_Ex_Ana_CondTopCount

这段代码定义了一个名为 GH_Ex_Ana_CondTopCount 的 Grasshopper 组件。它的主要功能是为 Excel 中的一个范围添加条件格式&#xff0c;具体是根据数值的大小高亮显示前N个&#xff08;或后N个&#xff09;数值。以下是该组件的详细介绍&#xff1a; 功能概述&#xff1a; 组件…

灵办AI搜索引擎和文档总结工具

前言—— 在信息爆炸的时代&#xff0c;如何高效地获取和处理知识成为了每个人面临的挑战。随着人工智能技术的迅猛发展&#xff0c;本文将深入探讨这一创新工具的功能与优势&#xff0c;以及如何在日常生活和工作中充分利用它&#xff0c;开启智能化的信息获取新篇章。 点击…

Part3-DOM学习笔记-操作元素

5.操作多个元素 5.1 排他思想 前面所述均为操作一个元素&#xff0c;给一个元素注册事件&#xff0c;如果是一组元素&#xff0c;就需要用循环的方式给元素注册事件。 我们想要给当前的元素实现某种样式&#xff0c;而其他的元素没有这个样式&#xff0c;这就需要用到排他思…

P2709 小B的询问

*原题链接* 非常简单的莫队板子题&#xff0c;让我们求出区间[l,r]中每个数出现次数的平方和&#xff0c;设枚举到,原来答案是res&#xff0c;如果加上后&#xff0c;则原来的变为&#xff0c;即res相比原来加上&#xff0c;删除同理。知道如何维护一个数的添加和删除后&#…

WIFI 配网

配网:指的是外部向WiFi模块提供SSID和密码&#xff0c;以便Wi-Fi模块可以连接指定的热点 常见的配网方式有:-键配网smart config、SoftAP配网、蓝牙配网、屏幕配网。 1.0 一键配网 2.0 蓝牙配网 一键配网的模式对应的厂加模式 3.0 状态机WIFI模组物联网 4.0 创建枚举结构体 ty…

Vue3.0项目实战(二)——大事件管理系统登录注册功能实现

目录 1. 登录注册页面 [element-plus 表单 & 表单校验] 1.1 注册登录 静态结构 & 基本切换 2. 注册功能 2.1 实现注册校验 2.2 注册前的预校验 2.3 封装 api 实现注册功能 3. 登录功能 3.1 实现登录校验 3.2 登录前的预校验 & 登录成功 1. 登录注册页面 […

Go反射四讲---第三讲:如何使用反射操作函数,获取函数的相关信息?

反射-函数 这是我们反射四讲的第三讲&#xff0c;本次给大家讲解如何使用反射处理函数相关的操作。 在这一部分&#xff0c;向大家展示如何输出方法的信息并执行调用。 输出信息&#xff0c;包含方法名&#xff0c;方法参数&#xff0c;返回值。 最后&#xff0c;如何使用反…

【小趴菜前端实习日记4】

el-table数据更新视图不更新的问题、el-dialog居中展示、el-form表单验证之对象属性验证、vue2过滤器 一、el-table数据更新视图不更新的问题二、el-dialog居中展示三、el-form表单验证之对象属性验证四、vue2过滤器 一、el-table数据更新视图不更新的问题 手动触发元素更新&a…

Linux:Socket网络编程

目录 1. 理解源 IP 地址和目的 IP 地址 2&#xff1a;认识端口号 3&#xff1a;端口号范围划分 4&#xff1a;理解源端口号和目的端口号 5&#xff1a;理解Socket(套接字) 6&#xff1a;两个传输协议 &#xff08;TCP/UDP&#xff09; 6.1&#xff1a;User Datagram Prot…

打卡55天------图论(并查集)

图论这里我学的不是很好&#xff0c;作为一名JavaScript前端开发工程师&#xff0c;我能说我基本上在工作中都没用到过吗&#xff1f; 一、并查集理论基础 这个说句实话&#xff0c;我平常工作很少用到&#xff0c;上学的时候好像也没学过&#xff0c;可能我只是本科生吧&…

USB3.2 摘录(10)

系列文章目录 USB3.2 摘录&#xff08;一&#xff09; USB3.2 摘录&#xff08;二&#xff09; USB3.2 摘录&#xff08;三&#xff09; USB3.2 摘录&#xff08;四&#xff09; USB3.2 摘录&#xff08;五&#xff09; USB3.2 摘录&#xff08;六&#xff09; USB3.2 摘录&…

如何使用双重IP代理实现更安全的网络访问

在进行网络爬虫或其他需要隐匿真实IP的操作时&#xff0c;单一的代理IP有时并不能完全满足我们的需求。为了进一步提高安全性和隐私保护&#xff0c;我们可以使用双重IP代理。本文将详细介绍如何使用Java实现双重IP代理&#xff0c;帮助你在网络环境中更加游刃有余。 什么是双重…

神经网络—卷积层

1.讲解 Conv2d out_channels 参数为2时&#xff0c;会生成两个卷积核&#xff0c;分别与输入进行卷积。得到的两个输出为输出 新生成的卷积核和原来的卷积核不一定相同 in_channels (int) – Number of channels in the input image out_channels (int) – Number of channels…

秋招突击——8/21——知识补充——计算机网络——cookie、session和token

文章目录 引言正文Cookie——客户端存储和管理Session——服务端存储和管理Token补充签名和加密的区别常见的加密算法和签名算法 面试题1、HTTP用户后续的操作&#xff0c;服务端如何知道属于同一个用户&#xff1f;如果服务端是一个集群机器怎么办&#xff1f;2、如果禁用了Co…

在线英语学习小程序App源码开发技术探讨

引言 随着信息技术的飞速发展和全球化进程的加快&#xff0c;英语学习已经成为越来越多人的日常需求。传统的纸质材料和课堂教学已经无法满足现代人灵活、高效的学习需求。因此&#xff0c;开发一款在线英语学习小程序App成为了一个热门话题。本文将从技术角度探讨在线英语学习…