架构篇34:深入理解微服务架构 - 银弹 or 焦油坑?

文章目录

    • 微服务与 SOA 的关系
    • 微服务的陷阱
    • 小结

微服务是近几年非常火热的架构设计理念,大部分人认为是 Martin Fowler 提出了微服务概念,但事实上微服务概念的历史要早得多,也不是 Martin Fowler 创造出来的,Martin 只是将微服务进行了系统的阐述(原文链接:https://martinfowler.com/articles/microservices.html)。不过不能否认 Martin 在推动微服务起到的作用,微服务能火,Martin 功不可没。

微服务的定义相信你早已耳熟能详,参考维基百科,我就来简单梳理一下微服务的历史吧(https://en.wikipedia.org/wiki/Microservices#History):

  • 2005 年:Dr. Peter Rodgers 在 Web Services Edge 大会上提出了“Micro-Web-Services”的概念。
  • 2011 年:一个软件架构工作组使用了“microservice”一词来描述一种架构模式。
  • 2012 年:同样是这个架构工作组,正式确定用“microservice”来代表这种架构。
  • 2012 年:ThoughtWorks 的 James Lewis 针对微服务概念在 QCon San Francisco 2012 发表了演讲。
  • 2014 年:James Lewis 和 Martin Fowler 合写了关于微服务的一篇学术性的文章,详细阐述了微服务。

由于微服务的理念中也包含了“服务”的概念,而 SOA 中也有“服务”的概念,我们自然而然地会提出疑问:微服务与 SOA 有什么关系?有什么区别?为何有了 SOA 还要提微服务?这几个问题是理解微服务的关键,否则如果只是跟风拿来就用,既不会用,也用不好,用了不但没有效果,反而还可能有副作用。

今天我们就来深入理解微服务,到底是银弹还是焦油坑。

微服务与 SOA 的关系

对于了解过 SOA 的人来说,第一次看到微服务这个概念肯定会有所疑惑:为何有了 SOA 还要提微服务呢?等到简单看完微服务的介绍后,可能很多人更困惑了:这不就是 SOA 吗?

关于 SOA 和微服务的关系和区别,大概分为下面几个典型的观点。

  • 微服务是 SOA 的实现方式

如下图所示,这种观点认为 SOA 是一种架构理念,而微服务是 SOA 理念的一种具体实现方法。例如,“微服务就是使用 HTTP RESTful 协议来实现 ESB 的 SOA”“使用 SOA 来构建单个系统就是微服务”和“微服务就是更细粒度的 SOA”。
img

  • 微服务是去掉 ESB 后的 SOA

如下图所示,这种观点认为传统 SOA 架构最广为人诟病的就是庞大、复杂、低效的 ESB,因此将 ESB 去掉,改为轻量级的 HTTP 实现,就是微服务。
img

  • 微服务是一种和 SOA 相似但本质上不同的架构理念

如下图所示,这种观点认为微服务和 SOA 只是有点类似,但本质上是不同的架构设计理念。相似点在于下图中交叉的地方,就是两者都关注“服务”,都是通过服务的拆分来解决可扩展性问题。本质上不同的地方在于几个核心理念的差异:是否有 ESB、服务的粒度、架构设计的目标等。
img

以上观点看似都有一定的道理,但都有点差别,到底哪个才是准确的呢?单纯从概念上是难以分辨的,我来对比一下 SOA 和微服务的一些具体做法,再来看看到底哪一种观点更加符合实际情况。

  1. 服务粒度

整体上来说,SOA 的服务粒度要粗一些,而微服务的服务粒度要细一些。例如,对一个大型企业来说,“员工管理系统”就是一个 SOA 架构中的服务;而如果采用微服务架构,则“员工管理系统”会被拆分为更多的服务,比如“员工信息管理”“员工考勤管理”“员工假期管理”和“员工福利管理”等更多服务。

  1. 服务通信

SOA 采用了 ESB 作为服务间通信的关键组件,负责服务定义、服务路由、消息转换、消息传递,总体上是重量级的实现。微服务推荐使用统一的协议和格式,例如,RESTful 协议、RPC 协议,无须 ESB 这样的重量级实现。Martin Fowler 将微服务架构的服务通讯理念称为“Smart endpoints and dumb pipes”,简单翻译为“聪明的终端,愚蠢的管道”。之所以用“愚蠢”二字,其实就是与 ESB 对比的,因为 ESB 太强大了,既知道每个服务的协议类型(例如,是 RMI 还是 HTTP),又知道每个服务的数据类型(例如,是 XML 还是 JSON),还知道每个数据的格式(例如,是 2017-01-01 还是 01/01/2017),而微服务的“dumb pipes”仅仅做消息传递,对消息格式和内容一无所知。

  1. 服务交付

SOA 对服务的交付并没有特殊要求,因为 SOA 更多考虑的是兼容已有的系统;微服务的架构理念要求“快速交付”,相应地要求采取自动化测试、持续集成、自动化部署等敏捷开发相关的最佳实践。如果没有这些基础能力支撑,微服务规模一旦变大(例如,超过 20 个微服务),整体就难以达到快速交付的要求,这也是很多企业在实行微服务时踩过的一个明显的坑,就是系统拆分为微服务后,部署的成本呈指数上升。

  1. 应用场景

SOA 更加适合于庞大、复杂、异构的企业级系统,这也是 SOA 诞生的背景。这类系统的典型特征就是很多系统已经发展多年,采用不同的企业级技术,有的是内部开发的,有的是外部购买的,无法完全推倒重来或者进行大规模的优化和重构。因为成本和影响太大,只能采用兼容的方式进行处理,而承担兼容任务的就是 ESB。

微服务更加适合于快速、轻量级、基于 Web 的互联网系统,这类系统业务变化快,需要快速尝试、快速交付;同时基本都是基于 Web,虽然开发技术可能差异很大(例如,Java、C++、.NET 等),但对外接口基本都是提供 HTTP RESTful 风格的接口,无须考虑在接口层进行类似 SOA 的 ESB 那样的处理。

综合上述分析,我将 SOA 和微服务对比如下:
img

因此,我们可以看到,SOA 和微服务本质上是两种不同的架构设计理念,只是在“服务”这个点上有交集而已,因此两者的关系应该是上面第三种观点

其实,Martin Fowler 在他的微服务文章中,已经做了很好的提炼:

In short, the microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery.

(https://martinfowler.com/articles/microservices.html)

上述英文的三个关键词分别是:small、lightweight、automated,基本上浓缩了微服务的精华,也是微服务与 SOA 的本质区别所在。

通过前面的详细分析和比较,似乎微服务本质上就是一种比 SOA 要优秀很多的架构模式,那是否意味着我们都应该把架构重构为微服务呢?

其实不然,SOA 和微服务是两种不同理念的架构模式,并不存在孰优孰劣,只是应用场景不同而已。我们介绍 SOA 时候提到其产生历史背景是因为企业的 IT 服务系统庞大而又复杂,改造成本很高,但业务上又要求其互通,因此才会提出 SOA 这种解决方案。如果我们将微服务的架构模式生搬硬套到企业级 IT 服务系统中,这些 IT 服务系统的改造成本可能远远超出实施 SOA 的成本。

微服务的陷阱

单纯从上面的对比来看,似乎微服务大大优于 SOA,这也导致了很多团队在实践时不加思考地采用微服务——既不考虑团队的规模,也不考虑业务的发展,也没有考虑基础技术的支撑,只是觉得微服务很牛就赶紧来实施,以为实施了微服务后就什么问题都解决了,而一旦真正实施后才发现掉到微服务的坑里面去了。

我们看一下微服务具体有哪些坑:

  1. 服务划分过细,服务间关系复杂

服务划分过细,单个服务的复杂度确实下降了,但整个系统的复杂度却上升了,因为微服务将系统内的复杂度转移为系统间的复杂度了。

从理论的角度来计算,n 个服务的复杂度是 n×(n-1)/2,整体系统的复杂度是随着微服务数量的增加呈指数级增加的。下图形象了说明了整体复杂度:
img

粗粒度划分服务时,系统被划分为 3 个服务,虽然单个服务较大,但服务间的关系很简单;细粒度划分服务时,虽然单个服务小了一些,但服务间的关系却复杂了很多。

  1. 服务数量太多,团队效率急剧下降

微服务的“微”字,本身就是一个陷阱,很多团队看到“微”字后,就想到必须将服务拆分得很细,有的团队人员规模是 5 ~ 6 个人,然而却拆分出 30 多个微服务,平均每个人要维护 5 个以上的微服务。

这样做给工作效率带来了明显的影响,一个简单的需求开发就需要涉及多个微服务,光是微服务之间的接口就有 6 ~ 7 个,无论是设计、开发、测试、部署,都需要工程师不停地在不同的服务间切换。

  • 开发工程师要设计多个接口,打开多个工程,调试时要部署多个程序,提测时打多个包。
  • 测试工程师要部署多个环境,准备多个微服务的数据,测试多个接口。
  • 运维工程师每次上线都要操作多个微服务,并且微服务之间可能还有依赖关系。
  1. 调用链太长,性能下降

由于微服务之间都是通过 HTTP 或者 RPC 调用的,每次调用必须经过网络。一般线上的业务接口之间的调用,平均响应时间大约为 50 毫秒,如果用户的一起请求需要经过 6 次微服务调用,则性能消耗就是 300 毫秒,这在很多高性能业务场景下是难以满足需求的。为了支撑业务请求,可能需要大幅增加硬件,这就导致了硬件成本的大幅上升。

  1. 调用链太长,问题定位困难

系统拆分为微服务后,一次用户请求需要多个微服务协同处理,任意微服务的故障都将导致整个业务失败。然而由于微服务数量较多,且故障存在扩散现象,快速定位到底是哪个微服务故障是一件复杂的事情。下面是一个典型样例。
img

Service C 的数据库出现慢查询,导致 Service C 给 Service B 的响应错误,Service B 给 Service A 的响应错误,Service A 给用户的响应错误。我们在实际定位时是不会有样例图中这么清晰的,最开始是用户报错,这时我们首先会去查 Service A。导致 Service A 故障的原因有很多,我们可能要花半个小时甚至 1 个小时才能发现是 Service B 返回错误导致的。于是我们又去查 Service B,这相当于重复 Service A 故障定位的步骤……如此循环下去,最后可能花费了几个小时才能定位到是 Service C 的数据库慢查询导致了错误。

如果多个微服务同时发生不同类型的故障,则定位故障更加复杂,如下图所示。
img

Service C 的数据库发生慢查询故障,同时 Service C 到 Service D 的网络出现故障,此时到底是哪个原因导致了 Service C 返回 Error 给 Service B,需要大量的信息和人力去排查。

  1. 没有自动化支撑,无法快速交付

如果没有相应的自动化系统进行支撑,都是靠人工去操作,那么微服务不但达不到快速交付的目的,甚至还不如一个大而全的系统效率高。例如:

  • 没有自动化测试支撑,每次测试时需要测试大量接口。
  • 没有自动化部署支撑,每次部署 6 ~ 7 个服务,几十台机器,运维人员敲 shell 命令逐台部署,手都要敲麻。
  • 没有自动化监控,每次故障定位都需要人工查几十台机器几百个微服务的各种状态和各种日志文件。
  1. 没有服务治理,微服务数量多了后管理混乱

信奉微服务理念的设计人员总是强调微服务的 lightweight 特性,并举出 ESB 的反例来证明微服务的优越之处。但具体实践后就会发现,随着微服务种类和数量越来越多,如果没有服务治理系统进行支撑,微服务提倡的 lightweight 就会变成问题。主要问题有:

  • 服务路由:假设某个微服务有 60 个节点,部署在 20 台机器上,那么其他依赖的微服务如何知道这个部署情况呢?
  • 服务故障隔离:假设上述例子中的 60 个节点有 5 个节点发生故障了,依赖的微服务如何处理这种情况呢?
  • 服务注册和发现:同样是上述的例子,现在我们决定从 60 个节点扩容到 80 个节点,或者将 60 个节点缩减为 40 个节点,新增或者减少的节点如何让依赖的服务知道呢?

如果以上场景都依赖人工去管理,整个系统将陷入一片混乱,最终的解决方案必须依赖自动化的服务管理系统,这时就会发现,微服务所推崇的“lightweight”,最终也发展成和 ESB 几乎一样的复杂程度。

小结

今天我们探讨了微服务与 SOA 的关系以及微服务实践中的常见陷阱,希望对你有所帮助。


【星猿杂谈】:在这里我们共同探索科技新趋势,分享积累的点滴,从编程语言到系统架构,从人工智能到高性能计算,我们追求技术的进步,同时珍视分享的力量。欢迎关注我们,在技术的精彩世界中一起遨游,发现更多未知!

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

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

相关文章

论文介绍 One-step Diffusion 只需单步扩散生成!

论文介绍 One-step Diffusion with Distribution Matching Distillation 关注微信公众号: DeepGo 源码地址: https://tianweiy.github.io/dmd/ 论文地址: https://arxiv.org/abs/2311.18828 这篇论文介绍了一种新的图像生成方法,名为分布匹配…

一、Docker/安装包部署ClickHouse

Docker/安装包部署ClickHouse 一、docker部署1.安装Docker2.拉取ClickHouse镜像2.1 选择拉取版本2.2 拉取镜像 3.启动ClickHouse3.1 确定好挂载目录3.2 测试环境3.3 生产环境3.1.1 获取配置文件3.1.2 配置文件中添加用户3.1.3 启动容器 4.使用DBeaver连接 二、安装包安装1.准备…

Seurat - 聚类教程 (1)

设置 Seurat 对象 在本教程[1]中,我们将分析 10X Genomics 免费提供的外周血单核细胞 (PBMC) 数据集。在 Illumina NextSeq 500 上对 2,700 个单细胞进行了测序。可以在此处[2]找到原始数据。 我们首先读取数据。 Read10X() 函数从 10X 读取 cellranger 管道的输出&…

Java实现陕西非物质文化遗产网站 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 设计目标2.2 研究内容2.3 研究方法与过程2.3.1 系统设计2.3.2 查阅文献2.3.3 网站分析2.3.4 网站设计2.3.5 网站实现2.3.6 系统测试与效果分析 三、系统展示四、核心代码4.1 查询民间文学4.2 查询传统音乐4.3 增改传统舞…

宿舍报修|宿舍报修小程序|基于微信小程序的宿舍报修系统的设计与实现(源码+数据库+文档)

宿舍报修小程序目录 目录 基于微信小程序的宿舍报修系统的设计与实现 一、前言 二、系统功能设计 三、系统实现 1、用户小程序功能模块 2、学生信息管理 3、维修人员管理 4、故障上报管理 5、论坛信息管理 四、数据库设计 1、实体ER图 2、具体的表设计如下所示&…

C++STL速查手册

本文参考cppreference,整理了一些常用的STL容器及其内置函数与算法,方便查用。 CSTL速查手册 什么是STL?STL模板 什么是STL? 在C中,STL 是指标准模板库(Standard Template Library)。STL 是 C 标…

【51单片机】LED点阵屏(江科大)

9.1LED点阵屏 1.LED点阵屏介绍 LED点阵屏由若干个独立的LED组成,LED以矩阵的形式排列,以灯珠亮灭来显示文字、图片、视频等。 2.LED点阵屏工作原理 LED点阵屏的结构类似于数码管,只不过是数码管把每一列的像素以“8”字型排列而已。原理图如下 每一行的阳极连在一起,每一列…

一周学会Django5 Python Web开发-Django5操作命令

锋哥原创的Python Web开发 Django5视频教程: 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计11条视频,包括:2024版 Django5 Python we…

2024.2.12日总结

今天去拜年去了,白天基本上都在外面,明天也是要去拜年,这几天学习的时间挺少的,但是还是要抓紧这些时间快点写项目,要找一些好用的插件,把项目和仓库新建好,然后下一步按照原型图的样子把页面画…

基础IO[一]

文件文件内容属性 文件在硬盘上放着,我们的流程->写代码->编译->运行->访问文件。那么本质上是谁在访问? 是进程在访问。进程访问文件是需要通过接口来访问。 文件在磁盘上放着,要向硬件写入文件,谁有权限呢?必须…

java之Maven

1. maven Maven是管理和构建java项目的工具 项目依赖资源(jar包)的管理,避免版本冲突统一项目结构项目构建,标准跨平台(Linux,window,MacOS)的自动化项目管理 2.maven依赖仓库 2.maven安装 maven安装视频教程 3. IDEA集成Maven 4. maven的依赖范围 5. maven生命…

从基建发力,CESS 如何推动 RWA 发展?

2023 年 11 月 30 日,Web3 基金会(Web3 Foundation)宣布通过 Centrifuge 将部分资金投资于 RWA(Real World Assets,真实世界资产),试点投资为 100 万美元。Web3 基金会旨在通过支持专注于隐私、…

代码随想录刷题笔记 DAY 24 | 回溯算法理论基础 | 组合问题 No. 77

文章目录 Day 2401. 回溯算法理论基础1.1 什么是回溯法?1.2 为什么要使用回溯法?1.3 如何理解回溯法? 02. 组合问题(No. 77)2.1 题目2.2 笔记2.3 代码 Day 24 01. 回溯算法理论基础 1.1 什么是回溯法? &…

网络安全检查表

《网络攻击检查表》 1.应用安全漏洞 2.弱口令,默认口令 3.服务器互联网暴露 4.操作系统,中间件安全漏洞 5.研发服务器,邮件服务器等安全检查

python+django高校活动报名场地管理系统l1ro4

校园活动管理平台程序的开发,在数据库的选择上面,选择功能强大的MySQL数据库进行数据的存放操作。 技术栈 后端:python 前端:vue.jselementui 框架:django Python版本:python3.7 数据库:mysql5…

交叉熵损失函数(Cross-Entropy Loss)的基本概念与程序代码

交叉熵损失函数(Cross-Entropy Loss)是机器学习和深度学习中常用的损失函数之一,用于分类问题。其基本概念如下: 1. 基本解释: 交叉熵损失函数衡量了模型预测的概率分布与真实概率分布之间的差异。在分类问题中&…

apk反编译修改教程系列---简单修改apk默认横竖屏显示 手机端与电脑端同步演示【十一】

往期教程: apk反编译修改教程系列-----修改apk应用名称 任意修改名称 签名【一】 apk反编译修改教程系列-----任意修改apk版本号 版本名 防止自动更新【二】 apk反编译修改教程系列-----修改apk中的图片 任意更换apk桌面图片【三】 apk反编译修改教程系列---简单…

Impala-架构与设计

架构与设计 一、背景和起源二、框架概述1.设计特点2.框架优点3.框架限制 三、架构图1.Impala Daemon2.Statestore3.Catalog 四、Impala查询流程1.发起查询2.生成执行计划3.分配任务4.交换中间数据5.汇集结果6.返回结果 总结参考链接 一、背景和起源 现有的大数据查询分析工具H…

Microsoft Word 超链接

Microsoft Word 超链接 1. 取消超链接2. 自动超链接2.1. 选项2.2. 校对 -> 自动更正选项2.3. Internet 及网络路径替换为超链接 References 1. 取消超链接 Ctrl A -> Ctrl Shift F9 2. 自动超链接 2.1. 选项 2.2. 校对 -> 自动更正选项 ​​​ 2.3. Internet…

AES加密后的密码可以破解吗

AES(高级加密标准)是一种广泛使用的对称加密算法,设计用来抵御各种已知的攻击方法。AES使用固定块大小的加密块和密钥长度,通常是128、192或256位。它被认为是非常安全的,到目前为止,没有已知的可行方法能够…