业务真的需要微服务吗

业务真的需要微服务吗

要说过去十年最火热的软件体系是什么,个人认为莫过于“微服务架构“了。从一线互联网架构师,到刚接触计算机软件不久的学生几乎都或多或少的了解过”微服务“相关知识了,其中在最出名的微服务体系要数 spring cloud 了。

在以众多互联网大厂为代表的微服务的宣传下,微服务架构的洪流也席卷到了各个中小厂商。但在部分场景下,微服务架构仅仅是因为有大厂背书,业务开发团队为了致敬大厂而选择了微服务架构,但恐怕有时候真的没有多维度对比过微服务架构和MVC 架构对各自业务场景的匹配度,因此现在部分团队在小范围实践“去微服务化”。说到这里,大家是不是也想到了最近两年呼声逐渐高涨的“下云”和“去中台化”,真可谓铁打的营盘,流水的技术。

回到正题,下面笔者会结合自己的工作体来分析一下微服务架构中大家容易忽视的部分,以帮助开发者更好的评估业务系统架构是否真的微服务化。

微服务概览

要理解微服务,首先需要了解微服务软件架构的演变。

单体架构

在早起的软件中,无论是前端还是后端,所有的功能都是放在一起的,这称为单体架构,也叫做巨石架构。顾名思义,整个软件系统就是单一的整体,仿佛一台一体化的机器。尽管软件内部也是模块化的设计,但在最终打包部署时是一个应用,如下图所示:

这里也可以想到,软件的功能越多,单体架构就会越复杂,很多缺点也随之暴露出来:

  • 所有功能耦合在一起,难以管理
  • 新功能迭代或 bug 修复,即使只修改一行代码,也需要重新构建和部署整个系统,成本非常高
  • 因为软件是一个整体,因此很难为每个功能开发和测试,只能整体开发和测试,导致基本必须采用瀑布式开发模型
  • 此外,最大的问题遍是当该系统庞大后,任何单个开发者几乎不可能完全搞懂这个系统,扩展性很低、可靠性很低。

总之,单体架构的大型软件,不仅开发速度慢,而且会形成难以维护和升级的复杂代码,成为开发者的沉重负担。

image-20240301233501024

面向服务架构

为了解决单体架构所遇到的问题,很早就有人提出必须打破代码耦合,拆分单体架构,将软件拆分成一个个独立的功能单元,每个功能单元可以以远程“服务”的形式提供,因此诞生了“面向服务架构”(service-oriented architecture,简称 SOA)。

"面向服务架构"就是把一个大型的单体服务,拆分成一个个独立服务,也就是较小的服务。每个服务都是一个独立的功能单元,承担不同的功能,服务之间通过通信协议连在一起。

如此看来这种架构有很多优点:

  • 拆分后的每个服务功能单一,相当于一个小型软件,便于开发和测试,也可以独立部署和升级
  • 各个服务独立运行,简化了架构,提高了可靠性
  • 扩展性好,可以容易地为每个独立的小软件加机器、加功能,承受高负载
  • 可靠性高,即使一个服务异常,不会影响到其他服务

此外,与单体架构不同,面向服务架构是语言不敏感的,不同服务可以使用不同的语言开发,也可以部署在不同的系统和环境。这意味着,面向服务架构默认运行在不同服务器上,每台服务器提供一种服务,多台服务器共同组成一个完整的软件系统。

image-20240303164607191

微服务架构

“微服务”的定义是这样的:围绕业务功能构建的,且每个服务关注单一业务,服务间采用轻量级的通信机制,可以全自动独立部署,可以使用不同的编程语言和数据存储技术。

看到这里,很多人会问,这和上面提到的面向服务架构(SOA)不是一样的吗?实则不然,SOA 更像是一种理念,而微服务则是 SOA 的一种实践,或许未来还会出现 SOA 的其他实践,因此”微服务“相当于是 SOA 的子集。

但细细想来,这又诞生了一个新的问题,随着一个单体应用被拆分未十几个甚至几十个服务,且每个服务又需要部署多个副本,因此这种架构给运维团队带来了极大的工作量。即使有 Ansible 等一系列的自动化工具诞生,也难以完全满足几何倍数增加的服务数带来的运维成本。直到 2014 年,Docker 的出现,彻底改变了软件世界的面貌。它让程序运行在容器中,每个容器可以分别设定运行环境,并且只占用很少的系统资源。此后,随着 Kubernetes 容器编排系统的出现,微服务架构也逐渐火热起来了。

image-20240303164607191

微服务的陷阱

Fred Brooks 在30年前写道,“there are no silver bullets”。但凡事有利就有弊,微服务架构也不是万能的。细细想来,他的缺点也是非常明显的:

  • 服务粒度划分,划分太细则服务太多,单个服务的复杂度确实下降了,但整个系统的复杂度却上升了

  • 微服务应用是分布式系统,开发者不得不使用 RPC 或者消息传递来实现服务间通信,还必须要写代码来处理服务间的鉴权、限流、消息传递速度过慢或者服务不可用等局部失效的问题

  • 服务模块间的依赖,应用的升级有可能会波及多个服务模块的修改

  • 测试微服务架构的应用是一项很复杂的任务

  • 微服务应用中各服务调用链路相比单体架构提升巨大,故障排查耗时多,对运维基础设施挑战大

服务划分颗粒度

举个例子,一个微服务架构的商城应用会有多少服务呢?首先,模块要分为账号模块、商品模块、订单模块和数据分析模块等等,如下图所示。如果这么划分,也算是一个小型的微服务了,看起来问题是不大的。但随着业务的发展和用户量的增加,服务肯定会做不同程序的拆分:

  • 账号:消费者账号和商家账号功能不同
  • 商品:商品店铺和用户搜索、浏览、详情并发数肯定是不一样的
  • 订单:实时下单和历史订单查询可用性要求不同
  • 数据分析:离线分析和实时分析两种场景

image-20240303202316859

久而久之,服务的数量会快速的增加,而不同的模块可能会由不同的团队负责开发,如果前期没有规范的业务模块,一个新功能开发后划分到具体哪个业务模块下是不明确的,而往往业务开发同学又仅仅关注功能的交付,久而久之,若后期涉及组织架构调整后,管理成本是很高的,甚至还会涉及一些互相扯皮的工作。

以鉴权和限流这两个分布式系统中最基本的功能为例,商品展示时会访问账号模块获取是否为会员,计算相应价格并展示,如果商品模块如果仅有一个服务,账号服务的鉴权和限流相关逻辑是十分容易实现的,即使账号模块有多个服务,我们也可以在框架的 filter 或 middleware 中实现,但当商品功能模块拆分为十几个微服务时,账号模块的认证限流信息即使能在 filter 活 middleware 中实现,其维护的各鉴权信息也是数量很多的。这还只是十几个,如果还需要维护成百个其他业务模块的鉴权信息时,成本是非常大的了。这里可能会想到,如果商品模块中不管多少个服务,统一使用一个认证鉴权密钥是否可以呢,当然可以,但这就又证明了服务模块的划分是非常重要的了,如果前期没有合理的划分,后面很多基础功能的实现成本都会很高。

那么如何合理的划分业务模块呢?其实如果业务前期用户量不大,我们并不一定要采用微服务架构,仅做前后端分离即可,同时保证后端各逻辑间解耦,当用户量增长后,能够快速将各子功能拆分未独立服务。同时每个业务模块应该只有一个统一的被调服务的入口,像 Kubernetes 的 APIServer 一样,与控制平面交互的入口只能有一个,被调用后,再由其将请求具体的逻辑服务。

全链路超时控制

单体应用时代,请求发送到了后端服务,剩余的逻辑基本是内部处理了,如果超时,基本不会涉及大批量的重试等逻辑。但分布式系统中,会存在大量的服务间调用,产生很多的网络消耗,因此对带宽的要求会变得很高,同时超时时间设置的不合理,甚至可能会导致整个系统雪崩。举个例子,现在有 ABCD 四个服务,调用关系、超时时间、重试次数均如图所示:

image-20240303211410586

假设 D 服务自身处理请求耗时 25s,当 A 收到请求并调用 B 时,是会超时并发起重试的,B 同理,虽然 C 访问 D 不会超时,但上游已经超时并发起重试了,而且这里的重试次数是 6 次,D 则会处理 6 次相同的请求,在高并发场景下,这会对 D 造成很大的负载,而越处于链路下游的服务越是基础服务,一旦雪崩会造成极大的生产事故。

因此建议在系统开发初期就确定合理的全链路超时控制的机制。

测试复杂性

微服务架构中,单个服务的变更可能会影响上下游多个服务的稳定性,因此上线前不能仅仅测试该服务的功能,更要和上下游服务联调测试。

故障排查成本

最后,在单体架构时代,故障排查登录少数几台服务器即可,但分布式系统中调用关系复杂,涉及服务众多,如果没有完善的运维平台,如合理且完善的格式化日志、分布式链路追踪等工具,排查问题将会非常耗时,成本很高。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CentOS安装Docker(黑马学习笔记)

Docker 分为 CE 和 EE 两大版本。CE 即社区版(免费,支持周期 7 个月),EE 即企业版,强调安全,付费使用,支持周期 24 个月。 Docker CE 分为 stable test 和 nightly 三个更新频道。 官方网站上…

作用域、解构、箭头函数

作用域 局部作用域 函数作用域(一直 存在) 块作用域(ES6,只有let和const有块级作用域&#xff0c;var没有) 块就是一对大括号&#xff0c;比如{ }、if(){ }、for(…){ } 使用var则失去块级作用域 //例如 for(var i1;i<3;i) {console.log(i)} console.log(i);//正确&…

Semantic human matting

1.introduction 数据集包括&#xff0c;时尚模特数据集&#xff0c;超过18.8w张模特图&#xff0c;从中选出35311张图片&#xff0c;DIM数据集&#xff0c;仅包含人类的图像&#xff0c;202个前景图像&#xff0c;背景来自coco数据集和互联网&#xff0c;背景图不含人类&#x…

SpringBoot整合MyBatis实现增删改查

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: 循序渐进学SpringBoot ✨特色专栏: MySQL学习 🥭本文内容: SpringBoot整合MyBatis实现增删改查 📚个人知识库: Leo知识库,欢迎大家访…

【问题解决】| 关于torch无法使用GPU的一些实验探索,思考

文章目录 1 研究背景2 问题解决2.1 问题一&#xff0c;这两个版本分别是怎么得到的&#xff1f;2.2 问题二&#xff0c;Windows下安装CUDA Tookit 是必须的吗&#xff1f;2.3 问题三&#xff0c;驱动版本必须大于等于运行时版本吗&#xff1f;2.4 问题四&#xff0c;只运行pip …

【大厂AI课学习笔记NO.56】(9)模型评测

作者简介&#xff1a;giszz&#xff0c;腾讯云人工智能从业者TCA认证&#xff0c;信息系统项目管理师。 博客地址&#xff1a;https://giszz.blog.csdn.net 声明&#xff1a;本学习笔记来自腾讯云人工智能课程&#xff0c;叠加作者查阅的背景资料、延伸阅读信息&#xff0c;及学…

微信小程序证书评级导致接口无法访问问题

微信小程序的ssl证书到期后&#xff0c; 更换了免费的ssl证书&#xff0c; 是在freessl网站申请的&#xff0c; 配置完了&#xff0c;后台可以访问https网页&#xff0c;但是小程序还是无法访问&#xff0c; 开始没有怀疑是https证书的问题&#xff0c; 调适了好长时间的代码&a…

前后端分离vue+nodejs高校体育运动会比赛系统08fv2-python-php-java

实现了一个完整的高校体育运动会比赛系统系统&#xff0c;其中主要有运动项目模块、学生模块、项目类型模块、用户表模块、token表模块、关于我们模块、收藏表模块、公告信息模块、留言板模块、运动论坛模块、配置文件模块、裁判员模块、比赛成绩模块、比赛报名模块、关于我们模…

9、taocms代码审计

一、XSS 1、DOM型xss 限制 无复现 payload: aa)alert(1)( 触发的参数&#xff1a;name代码 根据路由找到对应的文件&#xff0c;在api.php里接受全局变量action&#xff0c;最终赋值给$m,判断 如果$m不在数组就结束&#xff0c;新建方法复制给$model。检查类的方法是否存…

ctf_show笔记篇(web入门---爆破)

爆破 21&#xff1a;直接bp抓包跑字典&#xff0c;需base64加密 22&#xff1a;可用工具跑也可用浏览器找还可以用网上做好的域名查找去找 23&#xff1a;此题需跑脚本已经附上自写脚本 最后跑出来六个答案一个一个尝试得到答案为3j import hashlibm "0123456789qwert…

安卓之ContentProvider的应用场景以及优劣分析

摘要 本文旨在对Android开发中的ContentProvider进行深入探讨。ContentProvider是Android系统中四大组件之一&#xff0c;主要用于在不同的应用程序之间共享数据。本文首先对ContentProvider进行概述&#xff0c;然后分析其应用场景&#xff0c;接着对其优势和劣势进行分析&…

Linux设备模型(十一) - platform设备

一&#xff0c;platform device概述 在Linux2.6以后的设备驱动模型中&#xff0c;需关心总线、设备和驱动这3个实体&#xff0c;总线将设备和驱动绑定。在系统每注册一个设备的时候&#xff0c; 会寻找与之匹配的驱动&#xff1b;相反的&#xff0c;在系统每注册一个设备的时…

开发者38万+,鸿蒙开发岗为何却无人敢应聘?

鸿蒙校园公开课已走进135家高校&#xff0c;305所高校学生参与鸿蒙活动&#xff0c;286家企业参加鸿蒙生态学堂&#xff0c;38万开发者通过鸿蒙认证。 居上华为官方是说有通过鸿蒙开发者认证的已有38万。具体有多少开发者并没有明确表示。除此之外还有200家头部应用加速鸿蒙原…

【Golang切片】

切片 切片的引入内存分析切片的定义切片的遍历切片注意事项 切片的引入 【1】切片&#xff08;slice&#xff09;是golang中一种特有的数据类型 【2】数组有特定的用处&#xff0c;但是却有一些呆板&#xff08;数组长度固定不可变&#xff09;&#xff0c;所以在Go语言的代码…

面试题VUE篇

文章目录 Vue 的核心是什么/请简述你对 vue 的理解请简述 vue 的单向数据流槽口请简述Vue 常用的修饰符有哪些1. 普通修饰符2. 事件修饰符3. 键盘修饰符4. 系统修饰符 v-text 与{{}}与 v-html 区别v-on 可以绑定多个方法吗Vue 循环的 key 作用什么是计算属性Vue 单页面的优缺点…

最新版阿里云Linux CentOS7 ecs-user用户安装Mysql8详细教程(超简单)

经过两天的踩坑后&#xff0c;终于成功安装&#xff0c;并找到了最快捷的安装方式。接下来就由我来给大家介绍不踩坑安装大法&#xff01; 一、下载Mysql 首先前往Mysql官网下载 MySQL官方下载地址 第一步&#xff0c;选择安装包&#xff0c;这是最关键的一步&#xff0c;选错安…

进程与线程:通过实际生活来解析计算机的基本运作单位

进程与线程 进程与线程&#xff1a;详细解析计算机的基本运作单位1. 进程&#xff1a;独立的执行环境1.1 进程的特点&#xff1a; 2. 线程&#xff1a;轻量级的执行单元2.1 线程的特点&#xff1a; 3. 区别和联系4. 表格 进程与线程&#xff1a;详细解析计算机的基本运作单位 在…

AsConvSR | NTIRE2023-RTSR-Track1冠军方案

编辑 | Happy 首发 | AIWalker 链接 | https://mp.weixin.qq.com/s/p9u6RYkd37MmN12rUCMCuQ 前段时间&#xff0c;NTIRE2023各个竞赛落下帷幕&#xff0c;近期各个冠亚军方案提出者也在逐步公开方案细节。今天给大家概要介绍一下"RTSR-Track1"赛道冠军方案&#xff…

【Leetcode每日一题】前缀和(难度⭐)(25)

1. 题目解析 题目链接&#xff1a;DP34 【模板】前缀和 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 核心在于计算题目所给区间数组元素和返回即可。 2. 算法原理 为了提高计算效率&#xff0c;我们可以预先计算出一个「前缀…

【NDK系列】Android tombstone文件分析

文件位置 data/tombstone/tombstone_xx.txt 获取tombstone文件命令&#xff1a; adb shell cp /data/tombstones ./tombstones 触发时机 NDK程序在发生崩溃时&#xff0c;它会在路径/data/tombstones/下产生导致程序crash的文件tombstone_xx&#xff0c;记录了死亡了进程的…