您当前的位置:首页 > 电脑百科 > 程序开发 > 框架

我们什么时候应该转向微服务?

时间:2023-03-29 13:04:03  来源:今日头条  作者:科技狠活与软件技术

避免小型单体反模式。微服务在多大规模上才有意义?避免比问题更糟糕的解决方案,并了解权衡取舍。

上个月,我写了一篇关于模块化单体和现代单体架构的价值的文章。该文章(和视频)中出现的更有趣的讨论之一是逆向讨论:什么时候仍然选择微服务是正确的?

与任何设计选择一样,答案是主观的并且取决于很多因素。但是我们仍然可以使用一般的经验法则和全球指标。在我们进入这些问题之前,我们需要了解拥有微服务架构意味着什么。然后我们可以衡量拥有这样一个架构的好处和代价。

一个常见的误解是微服务只是简单地分解为单体。事实并非如此。我和很多仍然持有这种观点的人谈过,公平地说,他们可能有道理。AWS 是这样定义微服务的:

微服务是一种软件开发的架构和组织方法,其中软件由通过定义明确的 API 进行通信的小型独立服务组成。这些服务由独立的小型团队拥有。

微服务架构使应用程序更易于扩展和更快地开发,从而实现创新并加快新功能的上市时间。

较小的单体可能符合该定义,但如果您从字里行间中读到,则它们不符合。“独立”和“更易于扩展”这两个词暗示了这个问题。单体的问题(和优势)是单点故障。通过一项服务,我们通常可以更容易地发现问题。架构要简单得多。

如果我们将此服务分解成更小的部分,我们实际上会创建分布式故障点。如果链条上的一个部分出现故障,整个架构就会崩溃。这不是独立的,也不容易扩展。微服务不是小单体,分解单体不仅仅是处理较小的项目。这是关于改变我们的工作方式。

是什么造就了微服务?

一个好的微服务需要遵循以下健壮性和规模原则:

  • 按业务功能划分:这是一个逻辑划分。微服务是提供完整包的独立“产品”。这意味着负责微服务的团队可以在没有依赖关系的情况下进行业务所需的所有更改。
  • 通过 CI/CD 实现自动化:如果没有持续交付,更新成本将消除微服务的所有优势。
  • 独立部署:这是隐含的,因为对一个微服务的提交只会触发该特定服务的 CD。我们可以通过 Kube.NETes 和基础架构即代码 (IaC) 解决方案来实现这一点。
  • 封装:它应该隐藏底层的实现细节。服务充当独立产品,为其他产品发布 API。我们通常通过 REST 接口以及消息传递中间件来实现这一点。API 网关进一步增强了这一点。
  • 去中心化,没有单点故障:否则,我们会分散故障。
  • 故障应该被隔离:否则,单个服务宕机可能会产生多米诺骨牌效应。断路器可能是隔离故障的最重要工具。为了满足这种依赖性,每个微服务都处理自己的数据。这意味着很多数据库,有时可能具有挑战性。
  • 可观察的:这是处理大规模故障所必需的。没有适当的可观察性,我们实际上是盲目的,因为各个团队可以自动部署。

这一切都很好,但实际上这意味着什么?

它的大部分意思是我们需要对我们处理一些重要想法的方式做出几项重大改变。我们需要将更多的复杂性转移给 DevOps 团队。我们需要以不同的方式处理跨微服务的事务状态。这是处理微服务时最难掌握的概念之一。

在理想的世界中,我们所有的操作都将很简单,并包含在一个小型微服务中。围绕我们的微服务的服务网格框架将处理所有全球复杂性并为我们管理我们的个人服务。但这不是真实的世界。实际上,我们的微服务可能具有在服务之间传输的事务状态。外部服务可能会失败,为此,我们需要采取一些独特的方法。

依赖 DevOps 团队

如果您的公司没有优秀的 DevOps 和平台工程团队,微服务就不是一个选择。由于迁移,我们可能会部署数百个应用程序,而不是部署一个应用程序。虽然单个部署简单且自动化,但您仍然会在操作上投入大量工作。

当某些东西不起作用或无法连接时。当需要集成新服务或需要采用服务配置时。在使用微服务时,运营会承担更大的负担。这需要良好的沟通和协作。这也意味着管理特定服务的团队需要重新承担一些 OPS 负担。这不是一项简单的任务。

作为开发人员,我们需要了解许多用于将我们的单独服务绑定回单个统一服务的工具:

  • 服务网格:让我们组合独立的服务,并有效地充当它们之间的负载均衡器。它还提供安全、授权、流量控制等功能。
  • API 网关:应该使用而不是直接调用 API。这有时会很尴尬,但通常对于避免成本、防止速率限制等来说是必不可少的。
  • 特征标志和秘密:在单体中也很有用。但如果没有专用工具,它们就不可能在微服务规模上进行管理。
  • 熔断:让我们终止断开的 Web 服务连接并优雅地恢复。否则,单个损坏的服务可能会导致整个系统崩溃。
  • 身份管理必须是独立的:在处理微服务环境时,您无法摆脱数据库中的身份验证表。

我将跳过编排、CI/CD 等,但它们也需要针对出现的每项服务进行调整。其中一些工具对开发人员来说是不透明的,但我们在所有阶段都需要 DevOps 的帮助。

传奇模式

无状态服务将是理想的,承载状态会使一切变得更加复杂。如果我们将状态存储在客户端中,我们需要一直来回发送它。如果它在服务器上,我们将需要不断获取它、缓存它或将其保存在本地,然后所有交互都将针对当前系统执行。这消除了系统的可扩展性。

典型的微服务将存储在自己的数据库中并使用本地数据。需要远程信息的服务通常会缓存一些数据以避免往返于其他服务。这是微服务可以扩展的最大原因之一。在单体中,数据库应该成为应用程序的瓶颈,这意味着单体是高效的并且受限于我们存储和检索数据的速度。这有两个主要缺点:

  • 大小:我们拥有的数据越多;数据库越大,性能会同时影响所有用户。想象一下,查询亚马逊上每次购买的 SQL 表只是为了找到您的特定购买。
  • 域:数据库有不同的用例。一些数据库针对一致性、写入速度、读取速度、时间数据、空间数据等进行了优化。跟踪用户信息的微服务可能会使用时间序列数据库,该数据库针对与时间相关的信息进行了优化,而购买服务将专注于传统的保守 ACID 数据库。
  • 注意:一个整体可以使用多个数据库。这可以很好地工作并且非常有用。但这是例外。不是规则。

saga 模式通过使用补偿事务来撤销 saga 失败时的影响。当 saga 失败时,将执行补偿事务以撤消前一个事务所做的更改。这允许系统从故障中恢复并保持一致的状态。我们可以使用 Apache Camel 等工具来完成此操作,但这并非易事,并且需要比现代系统中的典型事务更多的参与。这意味着对于每个主要的跨服务操作,您都需要执行等效的撤消操作来恢复状态。那是不平凡的。有多种用于 saga 编排的工具,但这是一个超出本文范围的大主题,我仍然会从广义上对其进行解释。

了解 saga 的重要之处在于它避免了经典的 ACID 数据库原则,而侧重于“最终一致性”。这意味着操作会在某个时候使数据库处于一致状态。那是一个非常艰难的过程。想象调试一个只有在系统处于不一致状态时才会出现的问题。

下图从广义上展示了这个想法。假设我们有一个汇款流程:

对于汇款,我们需要先分配资金。

然后我们验证收件人是否有效且存在。

接下来,我们需要从我们的账户中扣除资金。

最后,我们需要将钱添加到收款人的帐户中。

那就是一笔成功的交易。对于常规数据库,这将是一个事务,我们可以在下图中左侧的蓝色列中看到它。但如果出现问题,我们需要运行相反的过程:

如果分配资金失败,我们需要移除分配。我们需要创建一个单独的代码块来执行分配的逆操作。

如果验证收件人失败,我们需要删除该收件人。然后我们还需要删除分配。

如果扣除资金失败,我们需要恢复资金,移除接收者,移除分配。

最后,如果向收款人添加资金失败,我们需要运行所有的撤销操作!

saga 中的另一个问题在 CAP 定理中得到了说明。CAP 代表一致性、可用性和分区容错性。问题是我们需要选择任意两个……别误会我的意思,你可能三个都选。但是,在失败的情况下,你只能保证两个。

可用性意味着请求收到响应。但不能保证它们包含最新的写入。

一致性意味着每次读取都会收到最近的错误写入。

容忍意味着即使许多消息在途中被丢弃,一切都会继续工作。

这与我们处理交易失败的历史方法大不相同。

我们应该选择微服务吗?

希望您了解正确部署微服务有多么困难。我们需要做出一些重大妥协。这种新方式不一定更好,在某些方面,它更糟。但是微服务的支持者还是有道理的,我们可以通过微服务获得很多,也应该关注这些好处。

我们预先提到了第一个要求:DevOps。拥有一支优秀的 DevOps 团队是考虑微服务的先决条件。我看到团队试图在没有 OPS 团队的情况下解决这个问题,他们最终花在操作复杂性上的时间比编写代码还多。这是不值得的努力。

微服务最大的好处是给团队的。这就是为什么拥有稳定的团队和范围至关重要的原因。将团队拆分成独立工作的垂直团队是一个巨大的好处。世界上模块化程度最高的单体无法与之抗衡。当我们有数百名开发人员单独跟踪 git 提交时,跟踪代码的规模变化就变得站不住脚了。微服务的价值只有在大团队中才能体现出来。这听起来很合理,但在创业环境中,事情突然发生了变化。我的一位同事在一家雇佣了数十名开发人员的初创公司工作。他们决定遵循微服务架构并构建了很多。然后是缩减和维护多种语言的数十种服务成为一个问题。

拆分单体很难但可行。将微服务统一到一个整体可能更难,我不知道有谁认真尝试过这样做但很想听听故事。

不是一个尺寸

要迁移到微服务架构,我们需要进行一些思维转变。一个很好的例子是数据库和用户跟踪微服务。在整体中,我们会将数据写入表并继续我们的工作。但这是有问题的。

随着数据规模的扩大,这个用户跟踪表最终可能包含大量数据,这些数据很难在不影响操作系统其余部分的情况下进行实时分析。通过微服务,我们可以提供几个优势:

微服务的接口可以使用消息传递,这意味着发送跟踪信息的成本将降至最低。

跟踪数据可以使用时间序列数据库,这对于这个用例来说会更有效。

我们可以流式传输数据并异步处理它以从该数据中获取额外的价值。

存在复杂性,数据将不再本地化。因此,如果我们异步发送跟踪数据,我们需要发送所有必要的信息,因为跟踪服务将无法返回到原始服务以获取额外的元数据。但它具有位置优势,如果有关跟踪存储的法规发生变化,则只有一个地方可以存储它。

动态控制和推出

您是否曾经按下过发布按钮导致生产中断?

我做了不止一次(太多次了)。那是一种可怕的感觉。微服务在生产中仍然会失败,并且仍然会发生灾难性的失败,但是,它们的失败通常是局部的。将它们推广到系统的特定子集 (Canary) 并进行验证也更容易。这些都是可以由实际掌握用户脉搏的人深入控制的策略:OPS。

微服务的可观察性是必不可少的、昂贵的,但也更强大。由于一切都发生在网络层,因此都暴露给可观察性工具。SRE 或 DevOps 可以更详细地了解故障。这是以开发人员为代价的,他们可能需要面对增加的复杂性和有限的工具。

应用程序可能会变得太大而不能失败。即使采用模块化,一些最大的单体应用也有如此多的代码,运行一个完整的 CI/CD 周期需要数小时。然后,如果部署失败,恢复到上一个好的版本也可能需要一段时间。

分割

过去,我们曾经根据层级划分团队。客户端、服务器、数据库等。这是有道理的,因为每一个都需要一套独特的技能。今天,垂直团队更有意义,但我们仍然有专长。

通常,移动开发人员不会在后端工作。但是假设我们有一个移动团队想要使用 GraphQL 而不是 REST。对于单体,我们要么告诉他们“接受它”,要么我们必须完成这项工作。有了微服务,我们可以用很少的代码为他们创建一个简单的服务。核心服务的简单外观。我们不需要担心移动团队编写服务器代码,因为这相对孤立。我们可以对每个客户层做同样的事情,这样更容易垂直整合一个团队。

太大

很难将手指放在使整体式应用不切实际的尺寸上,但这是您应该问自己的问题:

我们拥有或想要多少支球队?

如果你有几个团队,那么单体应用可能会很棒。如果您有十几个团队,那么您可能会在那里遇到问题。

衡量拉取请求和问题解决时间

随着项目的增长,您的拉取请求将花费更多时间等待合并,并且问题将需要更长的时间来解决。这是不可避免的,因为项目的复杂性趋于增加。请注意,新项目将具有更大的功能,一旦您在项目统计中考虑到生产力的下降应该是可衡量的,这可能会影响结果。

请注意,这是一个指标。在许多情况下,它可以指示其他事情,例如需要优化测试管道、审查流程、模块化等。

我们有知道代码的专家吗?

在某个时候,一个庞大的项目变得如此之大,以至于专家们开始忘记细节。当错误变得难以为继并且没有权威人物可以不经咨询就做出决定时,这就成为一个问题。

你愿意花钱吗?

微服务将花费更多。没有办法解决这个问题。在某些特殊情况下,我们可以调整规模,但最终,可观察性和管理成本将消除任何潜在的成本节约。由于人员成本通常超过云托管成本,因此总成本可能仍对您有利,因为如果规模足够大,这些成本可能会降低。

取舍

下面的雷达图很好地说明了单体与微服务的权衡。请注意,此图表是为大型项目设计的。项目越小,单体应用的前景就越好。

请注意,微服务在容错和团队独立性方面为大型项目带来了好处。但他们付出了代价。他们可以减少研发支出,但他们主要将其转移到 DevOps,因此这并不是一个主要的好处。

最后一句话

微服务的复杂性是巨大的,有时会被实施团队忽略。开发人员使用微服务作为一个大棒来抛弃他们不想维护的系统部分,而不是构建一个可持续的、可扩展的架构来取代单体。

我坚信项目应该从单体开始。微服务是扩展团队的优化,过早优化是万恶之源。问题是,什么时候做这样的优化合适?

我们可以使用一些指标来简化决策。最终,这种变化不仅仅是拆分单体。这意味着重新思考交易和核心概念。从单体开始,我们就有了一个蓝图,我们可以使用它来调整我们的新实现,因为它会加强。



Tags:微服务   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
对于微服务架构监控应该遵守的原则
随着软件交付方式的变革,微服务架构的兴起使得软件开发变得更加快速和灵活。在这种情况下,监控系统成为了微服务控制系统的核心组成部分。随着软件的复杂性不断增加,了解系统的...【详细内容】
2024-04-03  Search: 微服务  点击:(5)  评论:(0)  加入收藏
PHP+Go 开发仿简书,实战高并发高可用微服务架构
来百度APP畅享高清图片//下栽のke:chaoxingit.com/2105/PHP和Go语言结合,可以开发出高效且稳定的仿简书应用。在实现高并发和高可用微服务架构时,我们可以采用一些关键技术。首...【详细内容】
2024-01-14  Search: 微服务  点击:(115)  评论:(0)  加入收藏
九条微服务最佳实践,你学会了哪条?
微服务之间连贯一致的代码库对于可维护性至关重要。保持代码成熟度相似,可确保系统统一演进,防止服务间出现性能、安全性和功能差异。在开发微服务时,我们需要遵循哪些最佳实践...【详细内容】
2024-01-05  Search: 微服务  点击:(99)  评论:(0)  加入收藏
Go微服务入门到容器化实践
Go微服务入门到容器化实践Go 是一门高效、现代化、快速增长的编程语言,非常适合构建 Web 应用程序。而 Docker 是一种轻量级的容器化技术,能够使得您的应用程序在任何地方运行...【详细内容】
2024-01-01  Search: 微服务  点击:(63)  评论:(0)  加入收藏
微服务全做错了!谷歌提出新方法,成本直接降为1/9!
2023,微服务“水逆”之年。长期以来,不管大厂还是小厂,微服务都被认为是云原生服务应用程序架构的事实标准,然而2023,不止那位37signals的DHH决心下云,放弃微服务,就连亚马逊和谷歌...【详细内容】
2023-12-29  Search: 微服务  点击:(120)  评论:(0)  加入收藏
微服务架构中的数据一致性
在微服务中,一个逻辑上原子操作可以经常跨越多个微服务。即使是单片系统也可能使用多个数据库或消息传递解决方案。使用多个独立的数据存储解决方案,如果其中一个分布式流程参...【详细内容】
2023-12-27  Search: 微服务  点击:(143)  评论:(0)  加入收藏
监控 Spring Cloud 微服务的实践方案
一、简介Spring Cloud是一个基于Spring Boot实现的微服务框架,它提供了丰富的微服务功能,如分布式配置、服务注册与发现、服务熔断、负载均衡等。为了更好地管理和监控这样复...【详细内容】
2023-12-19  Search: 微服务  点击:(144)  评论:(0)  加入收藏
聊聊微服务链路服务
微服务架构图片如果有用户反馈某个页面很慢,我们知道这个页面的请求调用链是 A -----> C -----> B -----> D(图片有误),怎么来定位是由哪个服务引起的问题呢? 更进一步,如果...【详细内容】
2023-12-15  Search: 微服务  点击:(126)  评论:(0)  加入收藏
选择适合微服务的编程语言,让你的工作事半功倍!
讨论编程语言就像是一场政治辩论。每个开发者都会过分捍卫他/她所使用的编程语言。然而,编程语言应该被看作是它们真正是的东西,即一种工作工具。每种编程语言都有特定的目的...【详细内容】
2023-12-14  Search: 微服务  点击:(178)  评论:(0)  加入收藏
Eureka: 微服务架构中不可或缺的服务治理工具
Eureka是Netflix开源的一款用于服务治理的工具,它是NetflixOSS(OpenSourceSoftware)项目的一部分,主要用于实现微服务架构中的服务注册与发现。在当今庞大而复杂的微服务系统中,E...【详细内容】
2023-12-14  Search: 微服务  点击:(192)  评论:(0)  加入收藏
▌简易百科推荐
Web Components实践:如何搭建一个框架无关的AI组件库
一、让人又爱又恨的Web ComponentsWeb Components是一种用于构建可重用的Web元素的技术。它允许开发者创建自定义的HTML元素,这些元素可以在不同的Web应用程序中重复使用,并且...【详细内容】
2024-04-03  京东云开发者    Tags:Web Components   点击:(8)  评论:(0)  加入收藏
Kubernetes 集群 CPU 使用率只有 13% :这下大家该知道如何省钱了
作者 | THE STACK译者 | 刘雅梦策划 | Tina根据 CAST AI 对 4000 个 Kubernetes 集群的分析,Kubernetes 集群通常只使用 13% 的 CPU 和平均 20% 的内存,这表明存在严重的过度...【详细内容】
2024-03-08  InfoQ    Tags:Kubernetes   点击:(12)  评论:(0)  加入收藏
Spring Security:保障应用安全的利器
SpringSecurity作为一个功能强大的安全框架,为Java应用程序提供了全面的安全保障,包括认证、授权、防护和集成等方面。本文将介绍SpringSecurity在这些方面的特性和优势,以及它...【详细内容】
2024-02-27  风舞凋零叶    Tags:Spring Security   点击:(54)  评论:(0)  加入收藏
五大跨平台桌面应用开发框架:Electron、Tauri、Flutter等
一、什么是跨平台桌面应用开发框架跨平台桌面应用开发框架是一种工具或框架,它允许开发者使用一种统一的代码库或语言来创建能够在多个操作系统上运行的桌面应用程序。传统上...【详细内容】
2024-02-26  贝格前端工场    Tags:框架   点击:(47)  评论:(0)  加入收藏
Spring Security权限控制框架使用指南
在常用的后台管理系统中,通常都会有访问权限控制的需求,用于限制不同人员对于接口的访问能力,如果用户不具备指定的权限,则不能访问某些接口。本文将用 waynboot-mall 项目举例...【详细内容】
2024-02-19  程序员wayn  微信公众号  Tags:Spring   点击:(39)  评论:(0)  加入收藏
开发者的Kubernetes懒人指南
你可以将本文作为开发者快速了解 Kubernetes 的指南。从基础知识到更高级的主题,如 Helm Chart,以及所有这些如何影响你作为开发者。译自Kubernetes for Lazy Developers。作...【详细内容】
2024-02-01  云云众生s  微信公众号  Tags:Kubernetes   点击:(50)  评论:(0)  加入收藏
链世界:一种简单而有效的人类行为Agent模型强化学习框架
强化学习是一种机器学习的方法,它通过让智能体(Agent)与环境交互,从而学习如何选择最优的行动来最大化累积的奖励。强化学习在许多领域都有广泛的应用,例如游戏、机器人、自动驾...【详细内容】
2024-01-30  大噬元兽  微信公众号  Tags:框架   点击:(68)  评论:(0)  加入收藏
Spring实现Kafka重试Topic,真的太香了
概述Kafka的强大功能之一是每个分区都有一个Consumer的偏移值。该偏移值是消费者将读取的下一条消息的值。可以自动或手动增加该值。如果我们由于错误而无法处理消息并想重...【详细内容】
2024-01-26  HELLO程序员  微信公众号  Tags:Spring   点击:(86)  评论:(0)  加入收藏
SpringBoot如何实现缓存预热?
缓存预热是指在 Spring Boot 项目启动时,预先将数据加载到缓存系统(如 Redis)中的一种机制。那么问题来了,在 Spring Boot 项目启动之后,在什么时候?在哪里可以将数据加载到缓存系...【详细内容】
2024-01-19   Java中文社群  微信公众号  Tags:SpringBoot   点击:(86)  评论:(0)  加入收藏
花 15 分钟把 Express.js 搞明白,全栈没有那么难
Express 是老牌的 Node.js 框架,以简单和轻量著称,几行代码就可以启动一个 HTTP 服务器。市面上主流的 Node.js 框架,如 Egg.js、Nest.js 等都与 Express 息息相关。Express 框...【详细内容】
2024-01-16  程序员成功  微信公众号  Tags:Express.js   点击:(88)  评论:(0)  加入收藏
站内最新
站内热门
站内头条