服务拆分和远程调用(微服务)

news2025/2/4 2:31:56

博客主页:踏风彡的博客
博主介绍:一枚在学习的大学生,希望在这里和各位一起学习。
所属专栏:SpringCloud
文章创作不易,期待各位朋友的互动,有什么学习问题都可在评论区留言或者私信我,我会尽我所能帮助大家。

不管任何分布式的架构,它都离不开服务之间的拆分,细化,微服务也一样,下面,风哥来带大家一起了解一下微服务的服务拆分原则,并带大家通过一个小案例了解一下服务间拆分和远程调用吧😀。

1 服务拆分

1.1 服务拆分原则

​ 开头,风哥不墨迹了,把几个微服务之间的拆分原则先告诉大家。

  • 不同微服务之间,尽量不要有相同的业务,确保低耦合性
  • 每个微服务都应该有一个属于自己的独立数据库
  • 各个微服务之间,可通过微服务对外暴露的业务接口进行访问

在这里插入图片描述

1.2 服务拆分示例

1.2.1 实例的demo的结构如下:

在这里插入图片描述

请忽略eureka,它是下个章节的内容,学习的时候,做这个案例,一不小心没停下来😉。

在这里插入图片描述

cloud-demo:父工程

  • order-service:订单微服务,负责订单相关业务(当然这里只是一个小demo,只搞了一个查询的功能)
  • user-service:用户微服务,负责用户相关业务(功能也略少哈)

那么,根据上边服务拆分原则,可以得到如下结论(ps:没看下面的小伙伴们可以先看下上边,机灵的小脑袋瓜里先思考一下有什么结论):

  • 用户服务和订单服务都必须对外暴露Restful接口,供其他微服务调用
  • 两个服务之间如果要调用另一个微服务的功能,只能通过Restful接口调用,不能直接访问其他微服务的数据库
  • 所以,用户微服务和订单微服务要有自己独立的数据库

1.2.2 数据库表结构

Eg: cloud-order表中含有cloud-user的id字段。

在这里插入图片描述

在这里插入图片描述

​ 那个,导入工程啥的,在这我就不给具体流程了,大家学到了这里,相信都有这些基本能力了,接下来咱们直接根据这个演示服务拆分的小demo,来聊一下远程调用。

2 远程调用

2.1 远程调用实例

​ 在这里为了演示微服务间的远程调用,在这里就要设定需求场景了,先看原来demo的功能:

​ 先看一下两个微服务间需要交互的功能接口,这里的小demo只有一个,那就是查询订单的接口

@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;
    
    public Order queryOrderById(Long orderId) {
        // 1.查询订单
        Order order = orderMapper.findById(orderId);
        return order;
    }
}

​ 接下来启动服务,咱们看一下控制台返回的数据

在这里插入图片描述

​ 从上面,可以很清晰地看到user是空的,那么我们查询订单的时候想让它显示对应的user信息怎么办呢?

​ 这个时候,订单查询模块的接口就需要远程调用user模块的查询接口得到相应的user信息了。

​ 那么,不同模块之间的怎么调用其他模块的接口呢?

​ 有了这些疑问,接下来,大家跟着风哥一起探索一下吧。

2.2 案例需求

​ 在做一个功能时,我们的大体思路都是先确定需求,画好流程图,然后讨论,明确需求,再去实施,微服务同样也不例外。

​ 接下来,咱们看一下各个模块相互间的功能需求图,咱们这个小demo及其简单,微服务间的接口间的相互调用只有order-service中的查询接口的方法内去调用user-service中的查询接口,来,看需求图。

在这里插入图片描述

​ 看了需求图,相信大家对过程有了一个更清晰的了解,也明白接下来咱们需要做什么了,没错,我上句话已经说过了,order-service模块中的查询方法要向user-service模块发送一个http请求,调用http://localhost:8081/user/{userId}这个接口,获得相应的用户信息。

​ 然而呢,比较细心的小伙伴们,相信已经发现了现在风哥好像还没有说通过调用用户模块查询接口获取用户数据返回的数据类型是什么?有的人肯定会说,那肯定是User类型啊。这样说没错,但是说明咱们欠缺了思考,从另一个模块的接口获得数据,你这个模块里又没有相应的数据类型,你怎么将人家的数据封装成User类型呢?而这也恰恰是咱们需要学习远程调用中的一个关键部分。带着疑问出发学习更有劲,那么,跟着风哥来看一下具体的步骤吧。

​ 大概步骤:

  • 注册一个RestTemplate的实例并注入到Spring容器中取

  • 在order-service中修改OrderService类中的queryOrderById方法,根据Order对象中的userid查询user数据

  • 在OrderService类中注入RestTemplate的实例对象,通过调用它的getForObject()方法将指定url的数据封装成指定类型的数据

  • 将封装的User对象加入到Order对象中去,返回Order对象

    来,小伙伴们跟着风哥的步骤一起来做一下,let’s go.

步骤一 在order模块的启动类注册RestTemplate对象

​ 为什么选择在order模块的启动类中呢,因为在这个过程中,order模块的相应方法是一个消费者行为,user模块充当的是一个服务者行为,而关于消费者和服务者理论,我会放在文末进行描述。

@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }

    /**
     * 为了实现负载均衡
     * 创建RestTemplate并注入Spring容器中
     * @return
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

}

步骤二 调用相应接口获取并封装数据

​ 在这里,我把细分的2-4步合并为了一步,因为实现起来,不要问:风哥,为啥呢?因为它俩密不可分呐,拆开来描述是为了让大家更清晰地去了解具体流程,而现在实现则要根据实际情况啊,宝贝儿们。

  • 这里我为什么url前面用的是userservice,而不是其微服务模块对应的端口呢,这就涉及了Eureka的知识了,在这里没改是为了给大家先埋下个种子,让大家充满干劲去看本专栏下篇文章
  • restTemplate.getForObject(url, User.class):通过url调用相应的接口获取数据并封装成User数据类型
@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private RestTemplate restTemplate;

    public Order queryOrderById(Long orderId) {
        // 1.查询订单
        Order order = orderMapper.findById(orderId);
        //2.查询user
        //2.1.获取url地址
        String url = "http://userservice/user/"+order.getUserId();
        //2.2.根据url发起远程调用获取user
        User user = restTemplate.getForObject(url, User.class);
        //3.设置用户
        order.setUser(user);
        // 4.返回
        return order;
    }
}

最后返回所需要的order数据类型即可。

结果图

在这里插入图片描述

2.3 服务者和消费者

前面说好的哈,文末跟大家聊一聊服务者和消费者理论。

在服务调用关系中,都有两个不同的角色:

  • 服务者:即服务的提供方,说的现实一点,就是乙方啊😂
  • 消费者:调用服务的一方,也说现实一点,就是甲方啊😂

在咱们这个小案例demo中,服务者和消费者非常清晰。

在这里插入图片描述

但是,凡是没有绝对,就像相对静止状态一样,状态随时可能会变,可能下一个业务中user-service就成了消费方,而order就成了服务者了,所以,这要根据具体业务具体分析🐶。

​ 那么,好了,快乐的时光总是短暂的,风哥和小伙伴们在下篇文章中再见。

觉得文章对你有帮助的,辛苦动动小手,您的三连和关注就是博主创作的动力源泉。

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

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

相关文章

课程设计 | 教学设备管理系统

🎈 作者:Linux猿 🎈 简介:CSDN博客专家🏆,华为云享专家🏆,Linux、C/C、云计算、物联网、面试、刷题、算法尽管咨询我,关注我,有问题私聊! &…

SpringCloud微服务(二)——Eureka服务注册中心

Eureka服务注册中心 SpringCloud组件,Eureka已停更。 内容简介 1、Eureka是什么 Eureka 是 Netflix 开发的,一个基于 REST 服务的,服务注册与发现的组件,以实现中间层服务器的负载平衡和故障转移。服务注册:将服务…

[杂记]算法: 单调栈

0. 引言 单调栈, 顾名思义就是从栈底到栈顶元素单调递增或者单调递减的栈. 往往, 我们在解决寻找一个元素前面/后面的最远/最近处满足某条件的另一个元素的时候可以用到单调栈. 也是用两道算法题作为例子. 在这之前, 先简单写一下构造单调栈的模板. 如果我们需要从一个数组中…

ES6 入门教程 18 Iterator 和 for...of 循环 18.7 for...of 循环

ES6 入门教程 ECMAScript 6 入门 作者:阮一峰 本文仅用于学习记录,不存在任何商业用途,如侵删 文章目录ES6 入门教程18 Iterator 和 for...of 循环18.7 for...of 循环18.7.1 数组18.7.2 Set 和 Map 结构18.7.3 计算生成的数据结构18.7.4 类似…

供应叶酸PEG试剂Folic acid-PEG-Azide,FA-PEG-N3,叶酸-聚乙二醇-叠氮

1、名称 英文:Folic acid-PEG-Azide,FA-PEG-N3 中文:叶酸-聚乙二醇-叠氮 2、CAS编号:N/A 3、所属分类:Azide PEG Folic acid(FA) PEG 4、分子量:可定制,FA-PEG-N3 5…

Web安全之CTF测试赛

Web安全之CTF测试赛 1.000-我是谁 题目描述: 找到诈骗网站bsde.cn的域名注册人及邮箱,将域名注册人的126邮箱填写到下方答案框并点击送出 考察点:whois查询 whois查询网址: https://x.threatbook.com/ //微步在线 http://wh…

ES6 入门教程 17 Promise 对象 17.11 Promise.reject() 17.12 应用 17.13 Promise.try()

ES6 入门教程 ECMAScript 6 入门 作者:阮一峰 本文仅用于学习记录,不存在任何商业用途,如侵删 文章目录ES6 入门教程17 Promise 对象17.11 Promise.reject()17.12 应用17.12.1 加载图片17.12.2 Generator 函数与 Promise 的结合17.13 Promise…

ES6 入门教程 15 Proxy 15.2 Proxy 实例的方法 15.2.2 set() 15.2.3 apply()

ES6 入门教程 ECMAScript 6 入门 作者:阮一峰 本文仅用于学习记录,不存在任何商业用途,如侵删 文章目录ES6 入门教程15 Proxy15.2 Proxy 实例的方法15.2.2 set()15.2.3 apply()15 Proxy 15.2 Proxy 实例的方法 拦截方法的详细介绍。 15.2.…

【附源码】Python计算机毕业设计天润律师事务所管理系统

项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等等。 环境需要 1.运行环境:最好是python3.7.7,…

〖全域运营实战白宝书 - 运营角色认知篇③〗- 运营的底层逻辑是什么?

大家好,我是 哈士奇 ,一位工作了十年的"技术混子", 致力于为开发者赋能的UP主, 目前正在运营着 TFS_CLUB社区。 💬 人生格言:优于别人,并不高贵,真正的高贵应该是优于过去的自己。💬 &#x1f4e…

【笔试题】【day24】

文章目录第一题(完全二叉树的最多结点个数)第二题(哈夫曼树的带权路径长度)第三题(堆的重建)第四题(哈希映射的冲突)第一题(完全二叉树的最多结点个数) 一棵…

UE4 几种蓝图通信的方法

根据视频(UE4 几种蓝图通讯的方法)所做笔记 目录 方法一:通过公有变量 方法二:通过“获取类的所有actor”节点 方法三:通过蓝图接口 关卡蓝图与蓝图通信 方法一:通过公有变量 步骤: 1.新建…

一款php开发的非常好的OA办公管理系统源码

一款基于TP5 HAdmin Mysql打造的简单实用的开源的企业办公系统框架。可以帮助解决企业办公项目60的重复工作,让开发更多关注业务逻辑。既能快速提高开发效率,帮助公司节省人力成本,同时又不失灵活性。使用本系统可以简单快速地开发出企业级的…

如何将 MATLAB 源代码导出成 Java 的 JAR 包

文章目录编写 MATLAB 源文件安装 Java制作 JAR 包找到 MATLAB 的 JAR 包运行环境: MATLAB R2022a Java 8(1.8.0_311) Windows 10 教育版 64位 使用混合编程通常都不是好主意,但是有时候会遇到极端的情况。Java 擅长网络编程&am…

vivo霍金实验平台设计与实践-平台产品系列02

vivo 互联网平台产品研发团队 - Bao Dawei 本篇介绍了vivo霍金实验平台的系统架构以及业务发展过程中遇到的问题以及对应的解决方案。 《平台产品》系列文章: 1.vivo平台化实践探索之旅-平台产品系列01 一、前言 互联网企业经历过野蛮生长的开拓红利期之后&#xf…

UE4 TCP通信 (UE客户端与网络调试助手服务端、python服务端通信)

目录 一、使用UE4建立TCP客户端 二、使用网络调试助手建立服务端 三、基于网络调试助手的服务端与UE客户端通信 四、基于python的TCP服务端与UE客户端通信 一、使用UE4建立TCP客户端 1.在虚幻商城中搜索socket来下载TCP Socket Plugin插件 2.安装到引擎,目前…

面向对象分析与设计_类图

判断题 类与对象之间的关系,可以理解为模板与具体实例之间的关系 T 类是现实世界中客观存在的事物或实体。 F 类是具有相同属性和服务的一组对象的集合 T 对象的属性都有值,类的属性没有值 T 类的可见性描述了其属性和操作是否对于其他类可见&…

PHPer 开始使用 Java

出于工作需要,新项目要开始使用 Java 进行开发,注意力就要从 PHP 转移到 Java 上来。个人觉得这是一个挺好的机会,能接触被广泛使用的另一种开发语言和生态。 虽说语言之间存在许多相似之处,但真正落地的过程肯定会存在不少的曲折…

类加载与类文件结构

文章目录类加载机制为什么需要类加载类加载的时机类加载详细过程加载链接初始化类加载器类加载器的分类Java虚拟机自带的类加载器用户自定义类加载器ClassLoader的使用说明双亲委派机制沙箱安全机制类文件的结构类加载机制 为什么需要类加载 首先我们计算机的主要组成是输入设…

ES6 入门教程 15 Proxy 15.2 Proxy 实例的方法 15.2.10 ownKeys() ~ 15.2.12 setPrototypeOf()

ES6 入门教程 ECMAScript 6 入门 作者:阮一峰 本文仅用于学习记录,不存在任何商业用途,如侵删 文章目录ES6 入门教程15 Proxy15.2 Proxy 实例的方法15.2.10 ownKeys()15.2.11 preventExtensions()15.2.12 setPrototypeOf()15 Proxy 15.2 Pro…