翻译:多运行时微服务架构

这样文章通过Google翻译和人工逐字修改的方式完成的,某些位置也加上自己的理解。如有错误,请指出。

翻译这篇文章的目的其实是为了自己加深对微服务、分布式架构以及多运行时架构的理解。整篇文章从”战略“上分析了微服务”从古至今“解决的问题,以及带来的新问题;进而在“战术”层面,给出了解决这些新问题的手段。

个人见解:架构从来都是解决问题并带来问题, 取舍之道

背景知识

微服务的 12 要素:

  1. 基准代码:一份基准代码,多份部署
  2. 依赖:显式声明依赖关系
  3. 配置:在环境中存储配置
  4. 后端服务:把后端服务当做附加资源
  5. 构建、发布、运行:严格分离构建和运行
  6. 进程:以一个或多个无状态进程运行应用
  7. 端口绑定:通过端口绑定提供服务
  8. 并发:通过进程模型进行扩展
  9. 易处理:快速启动和优雅终止可最大化健壮性
  10. 开发环境与线上环境等价:尽可能的保持开发、预发布、线上环境相同
  11. 日志:把日志当做事件流
  12. 管理进程:后台管理任务当做一次性进程运行

原文从此处开始:

  • 创建分布式系统并非易事。围绕“微服务”架构和“ 12要素应用程序”设计出现了最佳实践。这些提供了与交付生命周期,网络,状态管理以及对外部依赖项的绑定有关的准则。
  • 但是,以可扩展和可维护的方式一致地实施这些原则是具有挑战性的。
  • 解决这些原理的以技术为中心的传统方法包括企业服务总线(ESB)和面向消息的中间件(MOM)。虽然这些解决方案提供了良好的功能集,但主要的挑战是整体架构以及业务逻辑和平台之间的紧密技术耦合。
  • 随着云,容器和容器协调器(Kubernetes)的流行,出现了解决这些原理的新解决方案。例如,Knative用于交付,服务网格用于网络,而Camel-K用于绑定和集成。
  • 通过这种方法,业务逻辑(称为“微逻辑”)构成了应用程序的核心,并且可以创建提供强大的现成分布式原语的sidecar“ mecha”组件。
  • 微观组件和机械组件的这种分离可以改善第二天的操作,例如打补丁和升级,并有助于维持业务逻辑内聚单元的长期可维护性。

创建良好的分布式应用程序并非易事:此类系统通常遵循12要素应用程序和微服务原则。它们必须是无状态的,可伸缩的,可配置的,独立发布的,容器化的,可自动化的,并且有时是事件驱动的和无服务器的。创建后,它们应该易于升级,并且长期可以承受。在当今的技术中,要在这些相互竞争的要求之间找到良好的平衡仍然是一项艰巨的努力。

在本文中,我将探讨分布式平台如何发展以实现这种平衡,更重要的是,在分布式系统的演进中还需要发生什么事情,以简化可维护的分布式体系结构的创建。如果您想让我实时谈论这个话题,请加入我的QCon 三月的伦敦。

分布式应用程序需求

在此讨论中,我将把现代分布式应用程序的需求分为四个类别-生命周期,网络,状态,绑定-并简要分析它们在最近几年中的发展情况。

生命周期 Lifecycle

  • 打包 Packaging
  • 健康检查 Healthcheck
  • 部署 Deployment
  • 扩展 Scaling
  • 配置 Configuration

让我们从基础开始。当我们编写一项功能时,编程语言将指示生态系统中的可用库,打包格式和运行时。例如,Java使用.jar格式,将所有Maven依赖项用作生态系统,并将JVM用作运行时。如今,随着发布周期的缩短,生命周期更重要的是能够自动部署,从错误中恢复以及扩展服务的能力。这组功能广泛地代表了我们的应用程序生命周期需求。

译者:错误恢复依赖健康检查

网络 Networking

  • 服务发现 Service Discovery
  • A/B 测试、金丝雀部署 A/B Testing,Canary rollouts
  • 重试、超时、断路器 Retry,timeout,circuit breaker
  • 点到点、发布/订阅 Point-to-point,pub/sub
  • 安全、可观测性 Security observability

从某种意义上讲,今天几乎每个应用程序都是分布式应用程序,因此需要联网。但是现代分布式系统需要从更广泛的角度掌握网络。从服务发现和错误恢复开始,到启用现代软件发布技术以及各种跟踪和遥测。为了我们的目的,我们甚至将不同的消息交换模式,点对点和发布/订阅方法以及智能路由机制包括在此类别中。

状态 State

  • 工作流管理 Workflow mgmt
  • 幂等性 Idempotency
  • 临时调度 Temporal scheduling
  • 缓存 Caching
  • 应用状态 Application State

当我们谈论状态时,通常是关于服务状态以及为什么最好是无状态的。但是管理服务的平台本身需要状态。这对于执行可靠的服务编排和工作流,分布式单例,临时调度(cron作业),幂等性,有状态的错误恢复,缓存等是必需的。此处列出的所有功能都依赖于底层的状态。虽然实际的状态管理不在本文讨论范围之内,但关注状态的分布式原语及其抽象却很受关注。

绑定 Binding

  • 连接器 Connectors
  • 协议转换 Protocol conversion
  • 消息转换 Message transformation
  • 消息路由 Message routeing
  • 事务性 Transactionality

分布式系统的组件不仅必须彼此对话,而且还必须与现代或旧式外部系统集成。这就要求连接器能够转换各种协议,支持不同的消息交换模式(例如轮询,事件驱动,请求/答复)转换消息格式,甚至能够执行自定义的错误恢复过程和安全机制。

译者:执行自定义的错误恢复过程和安全机制 – 事务

在不涉及一次性使用案例的情况下,以上内容代表了创建良好的分布式系统所需的通用原语的良好集合。如今,许多平台都提供了这样的功能,但是本文中我们要寻找的是过去十年中我们使用这些功能的方式如何变化,以及在下一个十年中它将如何变化。为了进行比较,让我们看一下过去的十年,看看基于Java的中间件如何满足这些需求。

传统中间件的限制

上一代的企业服务总线(ESB)及其变体(例如面向消息的中间件,更轻量级的集成框架等)可满足上述需求,这是一种众所周知的传统解决方案。ESB 是一种中间件,可以使用面向服务的体系结构(即经典SOA)在异构环境之间实现互操作性。

ESB可以为您提供良好的功能集,但ESB的主要挑战是整体架构以及业务逻辑和平台之间紧密的技术耦合,从而导致技术和组织集中化。在将服务开发并部署到这样的系统中时,它与分布式系统框架紧密结合,从而限制了服务的发展。这通常只会在软件生命周期的后期才变得明显。

以下是每类需求的一些问题和局限性,这些问题和局限性使得ESB在现代时代不再有用。

生命周期

在传统的中间件中,通常只有一个受支持的语言运行时(例如Java),它规定了软件的打包方式,可用的库,必须定期对其进行打补丁等。业务服务必须使用那些使其与以相同语言编写的平台紧密结合的库。实际上,这导致协调的服务和平台升级,从而阻止了独立和常规的服务和平台发布。

联网

尽管传统的中间件拥有围绕与其他内部和外部服务交互的高级功能集,但它具有一些主要缺点。 网络功能集中于一种主要语言及其相关技术。 对于Java来说,即JMS,JDBC,JTA等。更重要的是,网络问题和语义也深深地刻在业务服务中。 有一些具有抽象的库来解决网络问题(例如曾经很受欢迎的Hystrix项目),但是该库的抽象“泄漏”到了服务的编程模型,交换模式和错误处理语义以及库本身中。 虽然可以方便地在一个位置编写和读取与网络方面混合的整个业务逻辑,但是这将两个问题紧密地耦合到一个实现中,最终形成了一条共同的演进路径。

译者:这里问题在于一些通用的高级功能与语言绑定。这里提到的 Hystrix 作为断路器的一个实现,使用的时候需要采用 Hystrix 的编程模型。如果切换到其他的实现,则需要学习和改造的成本。

状态

为了进行可靠的服务编排,业务流程管理以及实施模式(例如Saga模式和其他运行缓慢的流程),平台需要在幕后保持持久状态。同样,临时动作(例如触发计时器和cron作业)建立在状态之上,并且需要在分布式环境中对数据库进行集群化和恢复。这里的主要约束是以下事实:与状态交互的库和接口没有完全抽象出来,也没有与服务运行时分离。通常,这些库必须配置有数据库详细信息,并且它们存在于服务中,从而将语义和依赖关系泄漏到应用程序域中

绑定

使用集成中间件的主要驱动程序之一是能够使用不同的协议,数据格式和消息交换模式连接到其他各种系统。但是,这些连接器必须与应用程序一起使用,这意味着必须将依赖关系与业务逻辑一起进行更新和修补。这意味着必须在服务内来回转换数据类型和数据格式。这意味着必须根据消息交换模式来构造代码并设计流程。这些是即使抽象的端点如何影响传统中间件中服务实现的一些示例。

译者:使用不同 RPC 实现的服务之间的对话,比如某个服务调用会同时(空间上)调用使用 Dubbo 协议的服务和使用 RESTful 协议的服务

云原生趋势

传统的中间件功能强大。它具有所有必要的技术功能,但缺乏现代数字业务需求所要求的快速更改和扩展的能力。这就是微服务体系结构及其设计现代分布式应用程序的指导原则所要解决的问题。

微服务背后的思想及其技术要求促进了容器和Kubernetes的普及和广泛使用。这开始了一种新的创新方式,这种方式将影响我们今后几年处理分布式应用程序的方式。让我们看看Kubernetes和相关技术如何影响每组需求。

生命周期

容器和Kubernetes将我们打包、分发和部署应用程序的方式发展为与语言无关的格式。关于Kubernetes模式和Kubernetes对开发人员的影响的文章很多,在这里我将简短介绍。但是请注意,对于Kubernetes,要管理的最小原语是容器,它专注于在容器级别和流程模型上交付分布式原语。这意味着它在管理应用程序的生命周期方面,运行状况检查、恢复、部署和扩展方面做得很好,但是在容器内的分布式应用程序的其他方面却没有做得那么好,例如灵活的网络、状态管理和绑定。

您可能会指出,Kubernetes具有状态工作负载、服务发现、cron作业和其他功能。的确如此,但是所有这些原语都是在容器级别的,并且在容器内部,开发人员仍然必须使用特定于语言的库来访问我们在本文开头列出的更详细的功能。这就是推动诸如Envoy、Linkerd、Consul、Knative、Dapr、Camel-K等项目的原因。

网络

事实证明,Kubernetes提供的围绕服务发现的基本网络功能是一个很好的基础,但对于现代应用程序来说还不够。随着微服务数量的增加和部署速度的加快,对更高级的发布策略、管理安全性、指标、跟踪、从错误中恢复、错误模拟等等方面的需求变得越来越具有吸引力,并产生了一种新的软件类别,称为服务网格。

这里更令人兴奋的是,趋势是将与网络相关的问题从包含业务逻辑的服务移出到单独的运行时(无论是sidecar还是节点级代理)。如今,服务网格可以执行高级路由、助力测试、处理安全性的某些部分,更甚至特定于应用程序的协议(例如,Envoy支持Kafka,MongoDB,Redis,MySQL等)。尽管作为解决方案的服务网格可能尚未得到广泛采用,但它触及了分布式系统中的真正痛点,我相信它将找到其形状和存在形式。

除了典型的服务机制外,还有其他项目,例如Skupper,这些项目证实了将网络功能放入外部运行时代理的趋势。Skupper通过第7层虚拟网络解决了多集群间的通信难题,并提供了先进的路由和连接功能。但是,Skupper并没有被嵌入到业务服务运行时中,而是每个Kubernetes命名空间运行一个实例,该实例充当共享的补充工具。

综上所述,容器和Kubernetes在应用程序的生命周期管理方面迈出了重要的一步。服务网格和相关技术遇到了真正的痛点,并为将更多职责从应用程序移到代理中奠定了基础。让我们看看下一步。

状态

我们在前面列出了依赖状态的主要集成原语。管理状态非常困难,应将其委派给专门的存储软件和托管服务。这不是这里的主题,而是在语言无关的抽象中使用状态来帮助集成用例。今天,许多努力试图在语言无关的抽象后面提供有状态的原语。有状态的工作流管理是基于云的服务中的强制性功能,例如AWS Step Functions,Azure Durable Functions等示例。在基于容器的部署中,CloudState和Dapr都依赖于sidecar模型来进一步解耦分布式应用程序中的状态抽象。

我也期待将上面列出的所有有状态功能抽象到一个单独的运行时中。这意味着工作流管理、单例、幂等、事务管理、cron作业触发器和有状态错误处理都可靠地发生在Sidecar(或主机级代理)中,而不是存在于服务中。业务逻辑不需要在应用程序中包含此类依赖关系和语义,并且可以从绑定环境中声明性地请求此类行为。例如,Sidecar可以充当cron作业触发器、幂等消费者和工作流管理器,而自定义业务逻辑可以作为回调调用或插入工作流的某些阶段、错误处理、临时调用或唯一幂等要求等。

另一个有状态用例是缓存。无论是由服务网格层执行请求缓存,还是使用诸如Infinispan,Redis,Hazelcast等之类的数据缓存,都有一些将缓存功能推到应用程序运行时之外的示例。

绑定

尽管我们的主题是将所有分布式需求与应用程序运行时脱钩,但这种趋势也继续伴随着绑定。连接器、协议转换、消息转换 、错误处理和安全中介都可以移出服务运行时。我们还没有到那里,但是在诸如Knative和Dapr之类的项目中朝这个方向进行了尝试。将所有这些职责移出应用程序运行时将导致更小,更注重业务逻辑的代码。这样的代码将在独立于分布式系统需求的运行时中运行,而分布式系统需求可以作为预包装功能使用。

Apache Camel-K 采用了另一种有趣的方法。该项目没有使用来伴随主应用程序的代理运行时,而是依靠智能的Kubernetes Operator来构建具有Kubernetes和Knative的附加平台功能的应用程序运行时。在这里,单一代理是负责包括应用程序所需的分布式系统原语的操作员。不同之处在于,某些分布式原语已添加到应用程序运行时中,而某些已在平台中启用(也可能包括Sidecar)。

未来架构趋势

概括地说,我们可以得出结论,通过将功能部件转移到平台级别,分布式应用程序的产品化达到了新的领域。除了生命周期之外,现在我们还可以观察到联网,状态抽象,声明性事件和端点绑定(拆箱即用),并且EIPs在此列表中排在后面。有趣的是,产品化使用进程外模型(sidecar)进行功能扩展,而不是使用运行时库或纯平台功能(例如新的Kubernetes功能)。

译者:产品化可以理解为分布式原语的内聚:便于独立发布和演进。

现在,我们通过将所有传统的中间件功能(也称为ESB)转移到其他运行时中来,不久,我们在服务中要做的就只是编写业务逻辑。

传统中间件平台和云原生平台概述

与传统的ESB时代相比,此体系结构将业务逻辑与平台更好地分离了,但是还没有完全分离。许多分布式原语,例如经典的企业集成模式(EIP):拆分器、聚合器、过滤器、基于内容的路由器;流处理模式:映射、过滤、折叠、联接、合并、滑动窗口;仍然必须包含在业务逻辑运行时中,许多其他依赖于多个不同且重叠的平台附加组件。

如果我们将在不同领域进行创新的各种云原生项目进行堆叠,那么最终将得到如下图所示:

多运行时微服务

这里的图仅用于说明目的,它有目的地选择代表性的项目并将其映射到分布式原语的类别。实际上,您不会同时使用所有这些项目,因为其中一些项目是重叠的且不兼容的工作负载模型。如何解释这个图?

  • Kubernetes和容器在多语言应用程序的生命周期管理中取得了巨大飞跃,并为未来的创新奠定了基础。
  • 服务网格技术通过高级网络功能在Kubernetes上进行了改进,并开始涉足应用程序方面。
  • 尽管Knative通过快速扩展主要专注于无服务器工作负载,但它也满足了服务编排和事件驱动的绑定需求。
  • Dapr以Kubernetes、Knative和Service Mesh的思想为基础,并深入应用程序运行时以解决有状态的工作负载、绑定和集成需求,充当现代的分布式中间件。

该图可帮助您直观地看到,很可能在将来,我们最终将使用多个运行时来实现分布式系统。多个运行时,不是因为有多个微服务,而是因为每个微服务都将由多个运行时组成,最有可能是两个运行时-自定义业务逻辑运行时分布式原语运行时

引入多运行时微服务

这是开始形成的多运行时微服务体系结构的简要说明。

您还记得科学家们制作的电影中的Avatar和机甲(机械套件),他们去旷野探索潘多拉吗?这种多运行时架构类似于这些Mecha-为类人动物驾驶员赋予超能力的套装。在电影中,您要穿上套装才能获得力量并获得破坏性武器。在这种软件架构中,您具有构成应用程序核心的业务逻辑(称为micrologic微逻辑)和提供强大且拆箱即用的分布式原语的sidecar mecha组件。微逻辑与mecha功能相结合,形成了一个多运行时微服务,该服务将进程外功能用于解决其分布式系统需求。最棒的是,Avatar 2即将面世,以帮助推广这种架构。我们最终可以在所有软件会议上用令人赞叹的机甲图片代替老式的边车摩托车;-)。接下来,让我们看看该软件体系结构的详细信息。

这是一个类似于客户端-服务器体系结构的两组件模型,其中每个组件都是独立的运行时。它与纯客户端-服务器体系结构的不同之处在于,这两个组件都位于同一主机上,彼此之间没有可靠的网络连接。这两个组件的重要性相同,它们可以在任一方向上启动操作并充当客户端或服务器。其中的一个组件称为为逻辑(Micrologic),它拥有从几乎所有分布式系统问题中剥离出来的非常少的业务逻辑。另一个随附的组件是Mecha,它提供了我们在本文中一直讨论的所有分布式系统功能(生命周期除外,它是一个平台功能)。

多运行时(进程外)微服务架构

Micrologic和Mecha可能是一对一的部署(称为sidecar模型),也可以是带有几个Micrologic运行时的共享Mecha。第一种模型最适用于Kubernetes等环境,而第二种模型则适用于边缘部署。

微逻辑运行时特征

让我们简要地探讨Micrologic运行时的一些特征:

  • Micrologic组件本身不是微服务。它包含微服务将具有的业务逻辑,但是该逻辑只能与Mecha组件结合使用。另一方面,微服务是自包含的,没有整体功能的一部分,也没有一部分处理流程扩展到其他运行时中。Micrologic及其与Mecha对应的产品的组合形成了微服务。
  • 这也不是函数或无服务器架构。无服务器最著名的是其提供的快速扩展和从零扩展到零的能力。在无服务器体系结构中,函数实现单个操作,因为这是可伸缩性的单位。在这方面,函数不同于实现多种操作的Micrologic,但实现方式不是端到端的。最重要的是,操作的实现分布在Mecha和Micrologic运行时上。
  • 这是客户端-服务器体系结构的一种特殊形式,针对无需编码即可使用众所周知的分布式原语进行了优化。另外,如果我们假设Mecha扮演服务器角色,那么每个实例都必须经过专门配置以便与单个客户端一起工作。它不是那种旨在与典型的客户端-服务器体系结构同时支持多个客户端的通用服务器实例。(译者:多运行时架构中假如 mecha 作为服务端,那么微逻辑作为客户端。客户端与服务端的关系多为一对一,或者多对一。而传统微服务架构中的客户端服务端一般是多对多)
  • Micrologic中的用户代码不会直接与其他系统交互,也不会实现任何分布式系统原语。它通过事实上的标准(例如HTTP / gRPC,CloudEvents规范)与Mecha进行交互,并且Mecha使用丰富的功能并在配置的步骤和机制的指导下与其他系统进行通信。
  • 尽管Micrologic仅负责实现从分布式系统问题中剥离出来的业务逻辑,但它仍必须至少实现一些API。它必须允许Mecha和平台通过预定义的API和协议与其进行交互(例如,通过遵循Kubernetes部署的云原生设计原则)。(译者:比如微逻辑需要实现健康检查的 API,方便平台-Kubernetes 或者 mecha 进行健康检查)

Mecha运行时特征

以下是一些Mecha运行时特征:

  • Mecha是一个通用的、高度可配置的、可重用的组件、提供分布式原语作为现成的功能。
  • Mecha的每个实例都必须配置为与一个Micrologic组件(边车模型)一起使用,或者配置为与几个组件共享(节点级别)。
  • Mecha不对Micrologic运行时做任何假设。它与使用开放协议和格式(例如HTTP / gRPC,JSON,Protobuf,CloudEvents)的多语言微服务甚至单片系统一起使用。
  • Mecha以简单的文本格式(例如YAML,JSON)声明性地配置,该格式表明要启用的功能以及如何将其绑定到Micrologic端点。对于专门的API交互,可以为Mechan附加规范,例如OpenAPI,AsyncAPI,ANSI-SQL等。对于由多个处理步骤组成的有状态工作流,可以使用诸如Amazon State Language的规范。对于无状态集成,可以使用与Camel-K YAML DSL类似的方法来使用企业集成模式(EIP)。这里的关键点是,所有这些都是Mecha无需编码即可实现的简单的、基于文本的、声明性的、多种语言的定义。请注意,这些都是未来派的预测,当前,没有用于状态编排或EIP的Mechas,但是我希望现有的Mechas(Envoy,Dapr,Cloudstate等)很快就会开始添加此类功能。Mecha是应用程序级别的分布式原语抽象层。
  • 与其为了不同目的而依赖于多个代理的(例如网络代理、缓存代理、绑定代理),而应该由一个Mecha提供所有这些功能。一些功能(例如存储、消息持久性、缓存等)的实现将被其他云或本地服务注入并支持。
  • 一些与生命周期管理有关的分布式系统问题可以由管理平台(例如Kubernetes或其他云服务)来处理,而不是使用通用的开放规范(例如Open App Model)提供的Mecha运行时。

这种架构的主要好处是什么?

好处是业务逻辑和越来越多的分布式系统问题之间的耦合变得松散。软件系统的这两个要素具有完全不同的动力学。业务逻辑始终是内部编写的唯一的自定义代码。它经常更改,具体取决于您的组织优先级和执行能力。另一方面,用于解决本文中列出的问题的分布式原语,并且众所周知。这些由软件供应商开发,并作为库,容器或服务使用。该代码根据供应商的优先级、发布周期、安全补丁、开放源代码管理规则等而更改。这两部分之间几乎不可见并且无法相互控制。

业务逻辑和分布式系统关注不同架构中的耦合

微服务原理有助于通过有限的上下文使不同的业务领域脱钩,每个微服务都可以独立发展。但是微服务架构无法解决将业务逻辑与中间件问题耦合在一起带来的困难。对于某些依赖于集成用例的微服务,这可能不是一个大因素。但是,如果您的领域涉及复杂的集成(也是越来越多的人所面临的),那么遵循微服务原则也无法帮助您避免与中间件的耦合。即使中间件是为您包含在微服务中的库,当您开始迁移和更改这些库时,这种耦合便会显现出来。还有您需要的分布的原语越多,您与集成平台的耦合就越强。通过预定义的API(而不是库)来访问作为独立运行时/进程的中间件,有助于解耦并实现每个组件的独立演进。

这也是为供应商分发和维护复杂的中间件软件的较好的方法。只要与中间件的交互是通过开放API和标准的进程间通信进行的,软件供应商就可以按照自己的节奏自由发布补丁和升级。消费者可以自由使用他们喜欢的语言、库、运行时、部署方法和过程。

这种架构的主要缺点是什么?

进程间通信。分布式系统的业务逻辑和中间件机制(您可以看到名称的来源)在不同的运行时中,并且需要HTTP或gRPC调用而不是进程内方法调用。但是请注意,这并不是跨机器或数据中心的网络调用。Micrologic运行时和Mecha应当位于同一主机上,并且延迟时间短,并且出现网络问题的可能性最小。

复杂。下一个问题是,是否值得为获得某些好处而进行复杂的开发、并维护此类系统。我认为答案将越来越倾向于是。分布式系统的需求和发布周期的步伐正在增加,并且此架构为此进行了优化。我前段时间写道,未来的开发人员必须具备混合开发技能。这种体系结构进一步证实了这一趋势。应用程序的一部分将使用高级编程语言编写,部分功能将由必须进行声明性配置的现成组件提供。这两个部分的互连不是在编译时或在启动时通过进程内依赖注入,而是在部署时通过进程间通信互连。该模型可实现更高的软件重用率和更快的变更速度。

微服务后无法使用的功能

微服务架构有一个明确的目标。它为变化而优化。通过将应用程序划分到业务域中,此软件架构通过独立的团队分离、管理并以独立的步调发布的服务,为软件演进和可维护性提供了最佳的服务边界。

如果我们看一下无服务器体系结构的编程模型,它主要基于功能。功能已针对可伸缩性进行了优化。通过功能,我们将每个操作分解为一个独立的组件,以便可以快速,独立和按需扩展。在此模型中,部署粒度是一项功能。之所以选择该函数,是因为它是代码结构:其输入的速率与缩放行为直接相关。这是一种针对极端可伸缩性(而不是复杂系统的长期可维护性)进行了优化的体系结构。

从AWS Lambda的流行及其完全托管的运营性质来看,Serverless的其他方面又如何呢?在这方面,“AWS无服务器”为配置速度进行了优化,但缺少控制和锁定功能。但是完全托管的方面不是应用程序体系结构,而是一种软件使用模型。它在功能上是正交的,类似于使用基于SaaS的平台,该平台在理想情况下应适用于任何类型的体系结构,无论是整体式、微服务、机甲还是功能。在许多方面,AWS Lambda类似于完全托管的Mecha架构,但有一个很大的区别:Mecha不执行功能模型,而是允许围绕业务域使用更具凝聚力的代码构造,而与所有中间件无关。

架构优化

另一方面,Mecha架构为中间件独立性优化了微服务。尽管微服务彼此独立,但它们在很大程度上依赖于嵌入的分布式原语。Mecha架构将这两个问题分为单独的运行时,从而允许独立团队独立发布它们。这种解耦可以改善第二天(day-2)的操作(例如修补和升级),并改善业务逻辑内聚单元的长期可维护性。在这方面,Mecha架构是微服务架构的自然发展,它通过根据引起最大摩擦的边界拆分软件来进行开发。与功能模型相比,该优化以软件重用和演化的形式提供了更多好处,而功能模型则以代码的过度分配为代价进行了优化,以实现极高的可伸缩性。

译者:day-2可以理解为前一天的发布带来的问题需要第二天的发布进行修复,而多运行时解耦了业务逻辑和分布式原语,允许其中一个的独立发布,不需要统一安排升级的节点。

结论

分布式应用程序有许多要求。创建高效的分布式系统需要多种技术和良好的集成方法。尽管传统的单体中间件提供了分布式系统所需的所有必要的技术功能,但它缺乏业务所需的快速更改、适应和扩展的能力。这就是为什么基于微服务的架构背后的思想为容器和Kubernetes的快速普及做出了贡献。随着云原生领域的最新发展,我们现在通过将所有传统中间件功能转移到平台和现成的辅助运行时中来全面发展。

应用程序功能的这种产品化主要是使用进程外模型进行功能扩展,而不是运行时库或纯平台功能。这意味着,将来很有可能我们将使用多个运行时来实现分布式系统。多个运行时,不是因为有多个微服务,而是因为每个微服务都将由多个运行时组成。自定义微业务逻辑的运行时,以及拆箱即用的分布式原语运行时。

关于作者

Bilgin Ibryam是Red Hat的首席架构师、提交者和Apache Software Foundation的成员。他是一位开源的传播者 、博客作者、偶尔的演讲者,并且是Kubernetes Patterns和Camel Design Patterns书籍的作者。在日常工作中,Bilgin乐于指导、编码并带领开发人员成功构建开源解决方案。他当前的工作集中在区块链、分布式系统、微服务、devops和云原生应用程序开发上。

原文的某些连接:

  • 12-Factors:https://12factor.net/zh_cn/
  • 原文:https://www.infoq.com/articles/multi-runtime-microservice-architecture/


文章同步发送到公众号:云编码 (微信号:sevenfeet)。

qrcode

comments powered by Disqus