微服务系列一:基础拆分实践

目录

前言

一、认识微服务

1.1 单体架构 VS 微服务架构 

1.2 微服务的集大成者:SpringCloud

1.3 微服务拆分原则

1.4 微服务拆分方式

二、微服务拆分入门步骤 :以拆分商品模块为例

三、服务注册订阅与远程调用:以拆分购物车为例

3.1 拆分模块、发现问题

3.2 问题分析、解决方法

3.3 实现远程调用:RestTemplate工具,实现端到端请求发送

四、微服务基础拆分总结

五、微服务基础追问巩固


前言

1. 微服务的基础入门篇,读完本文让你对微服务有一个基本的了解,与此同时通过两个微服务的模块拆分实验,发现微服务拆分面临的难题。并尝试去解决它。

2. 介绍微服务与单体架构的区别、微服务的拆分原则;解决跨微服务请求问题

一、认识微服务

        我觉得既然能看到这篇笔记,想必大家对微服务都是有一定的概念的。本篇文章是笔者在学习微服务、拆分微服务、解决拆分微服务中遇到的问题总结而来。是面向实践的。


参考下面这张项目架构演变图。微服务就是随着项目规模不断扩大,为了减轻服务器的压力、维持提高项目团队的高效协作、加快项目部署打包等功能提出的技术。

它将业务代码按照业务模块的不同,划分成多个小项目或是小模块,确保了每一个模块的职责明确,且分别部署到不同的一台或多台服务器上,减少服务器压力。

1.1 单体架构 VS 微服务架构 

单体架构:将业务的所有功能集中在一个项目中开发,打成一个包部署。

优点:(小规模下的优势)

  • 架构简单
  • 部署难度低 
  • 维护成本低

缺点:(大规模下的缺陷)

  • 团队协作难(就好像1个人盖楼100天、100人盖楼1天、100万人盖楼1分钟 可能吗? 人越多,在一个单体中开发、维护越来越困难)
  • 发布效率低 (单体打包几个G、几十个G甚至更大,浪费多少时间
  • 系统可用性差(对服务器压力大,别的业务请求量大的时候会影响其他正常的业务


微服务架构:是服务化思想指导下的一套最佳实践架构方案。服务化,就是把单体架构中的功能模块拆分为多个独立项目。

优点:(大规模下谈、小规模都不用)

  • 粒度小、发布效率高
  • 团队协调效率高
  • 单台服务器压力小

缺点:(大规模下谈、小规模都不用)

  • 需要解决不同业务之间的服务调用问题 (涉及到不同服务器之间的通信请求
  • 需要更多的部署成本 (服务器多了、项目的部署更加讲究

1.2 微服务的集大成者:SpringCloud

简单来说,微服务的概念很早就有了,但是家家不同。SpringCloud的出现,就像统一度量衡制定了一系列行业标准。

SpringCloud是目前国内使用最广泛的微服务框架。 SpringCloud集成了各种微服务功能组件,并基于SpringBoot实现了这些组件的自动装配,从而提供了良好的开箱即用体验。

官网学习Spring Cloud

这张图可重要啦,对应着我们在拆分微服务项目的时候会遇到的各种问题,SpringCloud都给出了相应的解决措施。


SpringCloud 与 SpringBoot的版本对照

由于目前企业使用jdk8、jdk11比较多,所有本次实验采用2021版Spring Cloud进行微服务搭建

1.3 微服务拆分原则

1. 单一职责原则

每个微服务应专注于执行单一的功能或业务领域。

2. 高内聚、低耦合

把相关的行为都聚集在一起,把不相干的行为放到其他地方。这样,当他们要修改某个行为的时候,只需要在一个地方修改即可,然后就能对该修改及早地进行发布。同时也有利于降低模块与模块之间的耦合性,提高每个模块的独立性。

如果要在很多不同的地方做修改,那么就需要同时发布多个微服务才能交付这个功能。修改进度不统一、测试工作不线性、部署工作不集中。从而大大降低开发效率。

3. 独立有边界

微服务应有明确定义的边界和功能。

1.4 微服务拆分方式

纵向拆分:按业务模块进行拆分,并遵循微服务拆分原则

横向补充:对于大家都会用到的公共服务,还可以在纵向基础上补充横向拆分,抽取公共服务,提高代码复用

目前广泛应用的两种微服务架构

1. 拆分独立若干project,分项目管理

这种拆分适合于超大规模的团队协调开发,项目完全解耦。

  • 优点:服务之间耦合度低

  • 缺点:每个项目都有自己的独立仓库,管理起来比较麻烦

2. 拆分依赖于主模块的若干子模块,统一Maven管理

这种拆分相对我们学习来说比较容易,一个项目内用不同的模块代表不同的服务

  • 优点:项目代码集中,管理和运维方便

  • 缺点:服务之间耦合,编译时间较长

二、微服务拆分入门步骤 :以拆分商品模块为例

本次实验以黑马商城的项目拆分为例,采用拆分模块的方式来进行微服务的学习:

2.1 入门拆分微服务步骤 

  • 第一步:新建微服务模块
  • 第二步:拷贝父工程的依赖坐标
  • 第三步:搭建基本框架,编写启动类
  • 第四步:拷贝配置文件,修改相关配置
  • 第五步:拷贝业务代码,遵循从 domain -- mapper -- service -- controller,注意检查导包
  • 第六步:连接数据库,确认微服务数据库
  • 第七步:测试项目 访问 接口文档 进行代码请求测试http://localhost:8081/doc.htmlicon-default.png?t=O83Ahttp://localhost:8081/doc.html

<!--来自父工程--><dependencies><!--common--><dependency><groupId>com.heima</groupId><artifactId>hm-common</artifactId><version>1.0.0</version></dependency><!--web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--数据库--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--mybatis--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><!--单元测试--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency></dependencies><build><finalName>${project.artifactId}</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>

2.2 解决商品模块的请求 500 问题

原因】 数据库连接失败,配置文件加载失败

解决措施】修改配置文件名即可

三、服务注册订阅与远程调用:以拆分购物车为例

3.1 拆分模块、发现问题

前面的拆分步骤照常,以下是拆分购物车模块遇到的问题

购物车微服务需要依赖商品微服务模块的方法,因此产生了报错,对此我们先采取注释的方式。先确保购物车微服务模块搭建运行成功后,后续我们再来通过SpringCloud的技术来解决这个问题。

接着配置数据库、将微服务部署到8082端口,启动访问测试:http://localhost:8082/doc.html

3.2 问题分析、解决方法

我们发现,拆分微服务的项目往往会面临这样一个问题:一个微服务需要注入另外一个微服务的方法或属性。

可是拆分微服务需要遵循一个原则:独立性、单一职责。也就是说我们不应该在购物车的微服务业务中注入过多的商品微服务模块的方法。

因此,我们需要思考如何让购物车微服务获取到商品微服务的方法同时又不破坏拆分原则呢?我们知道实际上我们发送的请求是一个完整的URL,可不可以这样做:我们模仿前端向后端发送请求的格式,让购物车发送获取商品信息的请求,这样一来不就解决问题了嘛

3.3 实现远程调用:RestTemplate工具,实现端到端请求发送

服务拆分之后,不可避免的会出现跨微服务的业务,此时微服务之间就需要进行远程调用。微服务之间的远程调用被称为RPC,即远程过程调用。

RestTemplate介绍

java开发中,使用http连接访问第三方网络接口,通常使用工具HttpClient和OKHttp。(后面讲)

如果使用spring框架,可以使用Spring给我们提供了一个RestTemplate工具,可以方便的实现Http请求的发送。

restTemplate默认的连接方式是java中的HttpConnection,可以使用ClientHttpRequestFactory指定不同的HTTP连接方式。

【使用步骤】

1. 在springboot项目中,需要使用RestTemplate的模块【cartcart-service】新建config配置

2. 注入RestTemplate对象

3. 使用RestTemplate方法进行代码修改

private void handleCartItems(List<CartVO> vos) {// 1.获取商品idSet<Long> itemIds = vos.stream().map(CartVO::getItemId).collect(Collectors.toSet());// 2.查询商品// 2.1 构建请求、发送请求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;}// 2.3 获取查询商品对象List<ItemDTO> items = response.getBody();if(CollUtils.isEmpty(items)) {return;}// 3.构建商品id与商品对象的映射Map<Long,ItemDTO> itemMap = items.stream().collect(Collectors.toMap(ItemDTO::getId, Function.identity()));//4. 写入VO对象返回前端for(CartVO v : vos) {ItemDTO item = itemMap.get(v.getItemId());if(item == null) {continue;}v.setNewPrice(item.getPrice()); // 最新价格v.setStock(item.getStock()); // 库存v.setStatus(item.getStatus()); // 状态}}

功能测试

四、微服务基础拆分总结

到此为止,事实上你已经可以搭建一个简易的微服务项目了。尽管这个微服务项目还有诸多问题和挑战。

例如你发现没有?在我们使用RestTemplate工具发送请求的时候,url是我们写死的。而且开发者需要非常清楚有这么一个方法,有这么一个方法的提供者,并且要知道提供者的具体地址。与此同时,如果服务的提供者宕机了,服务调用者也无法得知。这样的限制太大了。所以后期我们一定会寻求这方面的突破的。

在基础篇中,我们了解了微服务架构和单体架构的区别、学习了微服务拆分的模式和需要遵循的原则、尝试进行简单微服务模块的拆分并调试成功、成功发现跨微服务请求问题并初步尝试使用强大的RestTemplate去解决它......通过以上内容,相信你已经入门微服务了,接下来也能更好地去深入微服务项目的学习。

五、微服务基础追问巩固

1. 谈谈什么是微服务?什么时候要用微服务?目前主流的微服务技术有哪些?

2. 谈谈拆分微服务应该遵守哪些原则?你认为其中最有挑战性的是什么?

3. 详细讲解微服务的拆分步骤是什么?

4. 如果拆分过程中遇到要使用其他微服务提供的方法是,如何实现请求的远程调用?

5. 了解过RestTemplate没有?请谈谈你对RestTemplate的看法,具体的使用步骤是什么?

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

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

相关文章

jvm学习笔记-轻量级锁内存模型

一&#xff0c;轻量级锁 LockRecord的那个第一个成员变量是拷贝对应锁定了的java对象资源的MarkWord&#xff0c;Lock Record有一个Ptr指针刚开始指向自己&#xff0c;后面这个指针存储在锁定资源的java对象的markword中&#xff0c;后续可以通过java对象的MarkWord快速定位到…

【力扣专题栏】面试题 01.02. 判定是否互为字符重排,如何利用数组模拟哈希表解决两字符串互排问题?

题解目录 1、题目描述解释2、算法原理解析3、代码编写(1)、两个数组分别模拟哈希表解决(2)、利用一个数组模拟哈希表解决问题 1、题目描述解释 2、算法原理解析 3、代码编写 (1)、两个数组分别模拟哈希表解决 class Solution { public:bool CheckPermutation(string s1, stri…

指针和内存地址的关系(uint8_t和uint32_t的指针有什么区别)

指针在我们的学习中非常常见&#xff0c;有些人只是了解指针的基本概念&#xff0c;却不知道他的原理&#xff0c;到时候使用起来一头雾水&#xff0c;接下来我将对指针做出一些解释说明。 一、数据是如何存储的&#xff1a; 我们初始化一个int变量a,变量a会存储到内存中&#…

flutter 专题四 Flutter渲染流程

一、 Widget - Element - RenderObject关系 二、 Widget 、Element 、RenderObject 分别表示什么 2.1 Widget Widget描述和配置子树的样子 Widget就是一个个描述文件&#xff0c;这些描述文件在我们进行状态改变时会不断的build。但是对于渲染对象来说&#xff0c;只会使用最…

高效内容营销策略提升品牌影响力与客户忠诚度

内容概要 内容营销是一种通过创造和分享有价值的内容&#xff0c;以吸引特定目标受众并促进品牌发展的策略。这种营销形式不仅仅注重产品的直接推广&#xff0c;更着眼于与受众之间建立长期的信任关系。有效的内容营销能够提升品牌在市场中的影响力和客户的忠诚度&#xff0c;…

git 入门作业

任务1: 破冰活动&#xff1a;自我介绍任务2: 实践项目&#xff1a;构建个人项目 git使用流程&#xff1a; 1.将本项目直接fork到自己的账号下&#xff0c;这样就可以直接在自己的账号下进行修改和提交。 这里插一条我遇到的问题&#xff0c;在fork的时候没有将那个only camp4的…

NumPy Ndarray学习

1.NumPy Ndarray 对象简介 NumPy 最重要的特点是其 N 维数组对象 ndarray&#xff0c;它是一系列同类型数据的集合&#xff0c;以 0 下标为开始进行集合中元素的索引。ndarray 对象是用于存放同类型元素的多维数组。ndarray 中的每个元素在内存中都有相同存储大小的区域。 2.N…

网络层3——IP数据报转发的过程

目录 一、基于终点的转发 1、理解 2、IP数据报转发过程 二、最长前缀匹配 1、理解 2、主机路由 3、默认路由 三、二叉线索查找 一、基于终点的转发 1、理解 理解什么叫终点转发 IP数据报的传递&#xff0c;交给路由器后 可不可以做到直接发送给目的主机呢&#xff1f;…

【UGUI】为射击游戏添加动态显示的分数和血量到UI界面

项目背景 在这个项目中&#xff0c;我们希望实现一个简单的游戏系统&#xff0c;其中玩家可以通过击中目标来获得分数&#xff0c;同时通过与怪物碰撞来减少血量。分数和血量需要在游戏界面上实时显示&#xff0c;以便玩家能够随时了解自己的状态。 技术实现 1. 静态变量的使…

「C/C++」C/C++标准库 之 #include<cstdlib> 通用工具函数库

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「C/C」C/C程序设计&#x1f4da;全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasoli…

CTF压缩包破解神器bkcrack教程和详细使用过程

kali安装bkcrack教程和详细使用过程 1.bkcrack介绍&#xff1a;2.bkcrack功能&#xff1a;3.bkcrack安装&#xff1a;Linux-Kali下&#xff1a;测试&#xff1a;Windows下安装&#xff1a; 4.bkcrack的使用方法&#xff1a;4.1查看相关参数4.2恢复内部密钥从 zip 档案中加载数据…

基于Python的乡村居民信息管理系统【附源码】

基于Python的乡村居民信息管理系统 效果如下&#xff1a; 系统主页面 系统登录页面 管理员主页面 居民管理页面 政务学习页面 土地信息管理页面 个人信息管理页面 居民登陆页面 村委人员主页面 研究背景 随着信息技术的飞速发展和乡村振兴战略的深入实施&#xff0c;传统的乡…

UI设计公司—兰亭妙微—提供轨道交通行业UI设计

蓝蓝设计工作室2008年开始&#xff0c;2011年正式成立北京兰亭妙微科技有限公司&#xff0c;主创清华团队&#xff0c;专注软件和互联网ui设计开发&#xff0c;擅长企业信息化管理、监控、大数据软件UIUE咨询和设计开发服务。立足UI&#xff0c;一直在学习进步。交通行业UE UI解…

2-Ubuntu/Windows系统启动盘制作

学习目标&#xff1a; 掌握使用Win32DiskImager、Rufus等工具制作系统启动盘的基本步骤。独立将ISO镜像文件写入USB闪存驱动器&#xff0c;确保在需要时顺利安装或修复系统。通过学习如何选择正确的源文件和目标驱动器&#xff0c;理解启动盘的使用场景和注意事项&#xff0c;…

Java项目管理与SSM框架介绍

Maven简介 Maven是一个项目管理工具。它可以帮助程序员构建工程&#xff0c;管理jar包&#xff0c;编译代码&#xff0c;完成测试&#xff0c;项目打包等等。Maven工具是基于POM&#xff08;Project Object Model&#xff0c;项目对象模型&#xff09;实现的。在Maven的管理下每…

CGAL生成简单形状

三角形 四边形 立方体 六面体 棱柱 锥体 二十面体 网格 Polyhedron _mesh;/**************三角形************/CGAL::make_triangle(K::Point_3(100, 0, 0), K::Point_3(0, 100, 0), K::Point_3(0, 0, 0), _mesh);CGAL::IO::write_polygon_mesh("F:/WORK/STL/triangle.stl…

江协科技STM32学习- P30 FlyMCU串口下载STLink Utility

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…

【Python】【数据可视化】【商务智能方法与应用】课程 作业一 飞桨AI Studio

作业说明 程序运行和题目图形相同可得90分&#xff0c;图形显示有所变化&#xff0c;美观清晰可适当加分。 import matplotlib.pyplot as plt import numpy as npx np.linspace(0, 1, 100) y1 x**2 y2 x**4plt.figure(figsize(8, 6))# yx^2 plt.plot(x, y1, -., labelyx^2,…

提高后端接口性能的方法

个人bibilailai&#xff08;不喜请跳过&#xff09;&#xff1a;前几天参加的部门技术分享会&#xff0c;同事分享了一个内容为“提高接口性能的常见技巧”&#xff0c;个人觉得很有用&#xff0c;所以想在这里分享给大家&#xff0c;希望对刚入职场不久的兄弟姐妹们有所帮助。…

.net Core 使用Panda.DynamicWebApi动态构造路由

我们以前是通过创建controller来创建API&#xff0c;通过controller来显示的生成路由&#xff0c;这里我们讲解下如何不通过controller&#xff0c;构造API路由 安装 Panda.DynamicWebApi 1.2.2 1.2.2 Swashbuckle.AspNetCore 6.2.3 6.2.3添加ServiceAction…