【ArchSummit架构师峰会】探讨数据与人工智能相互驱动的关系>>> 了解详情
写点什么

云绑定应用:实现业务逻辑,减轻开发者负担

作者:Bilgin Ibryam

  • 2023-05-31
    北京
  • 本文字数:6814 字

    阅读完需:约 22 分钟

云绑定应用:实现业务逻辑,减轻开发者负担

随着对应用为先的云服务采用愈发广泛,应用与云服务的融合程度也到了前所未有的深度。应用程序和云运行时的边界从虚拟机转移到了容器和函数中。集成边界从仅使用数据库和消息代理访问,转换成应用程序的机械部分在云中的混合运行。在这些因素影响下的架构中,应用程序与“云绑定”,应用逻辑与管理责任转移至云服务中,允许开发者专注于业务逻辑。

 

本文中将分析,通过使用具备灵活性和可移植性的公开 API 和标准将应用程序与云服务绑定,所带来的软件全栈平价化。

内部架构的演变


应用程序的内部架构通常归属于单一团队掌控。内部的边界则由所选编程语言、运行时、工具,以及包、模块、接口、类、函数等抽象协助开发者进行控制。领域驱动设计(DDD)协助开发者构建领域模型,用抽象概念封装服务业务逻辑,缓解业务实际与代码之间的鸿沟。

 

HexagonalOnion,以及 Clean 架构可以与 DDD 相互补,以不同边界与外部基础设施依赖划分应用程序代码。虽然这些方式最初都是颇具创新意识且时至今日仍然适用,但这些架构的设计初衷只考虑了包含 JSP、Servlet、部署于共享应用运行时的 EJB 这三层的 Java 应用程序,当年设计的重点还是应用逻辑与 UI、数据库解耦,实现独立测试方面。

 


图一:内部应用架构

 

后来,微服务、十二因素应用程序等新挑战、新概念层出不穷,应用程序的设计方式也受此影响。微服务的核心是将应用逻辑切分为归属单一团队的独立可部署单元,十二因素应用程序方法意在构建可在动态云环境中运行、扩展的分布式无状态应用。这些架构所引入的原则和最佳实践改写了我们构建应用程序内部架构并管理的方式。

 


图二:应用程序架构演变时间线

 

在应用程序架构演变时间线的后半段,容器的采用和 Kubernetes 的引入成为主流,彻底改变了应用打包、协调的方式。AWS Lambda 引入了高度可扩展的功能即服务(FaaS)的概念,将应用程序细粒度概念再度拔高,将完整的基础设施管理责任卸至云供应商。其他如服务网格、Mecha 架构等技术潮流的出现,网络和分布式开发者基元等非功能性应用栈平价化并剥离至 sidecar 中。受微服务启发,数据网格架构设计意图将应用程序的数据分析架构拆分至更小的独立数据域中,让每个域都有自己的项目和团队。再加上近期的应用为先云服务等等,这一系列技术潮流开始重塑应用程序的外部架构,本文中我将这些统一称为“云绑定应用”。

 

外部架构演变


外部架构是应用与其他团队和组织以专门的内部中间件、存储系统,或云服务等形式拥有的其他应用和基础设施交互的部分。应用与外部系统相连并卸除部分责任的方式构建了外部架构。为充分利用基础设施,应用需要与该基础设施绑定,确立明确分界线以保留其敏捷性。应用的内部架构和实现应独立进行修改,并在不变动内部的情况下与云服务等外界依赖关系互换。

 


图三:外部引用架构

 

大体上来说,我们可以将应用程序与其周围环境相绑定的方式分为两类。

 

  • 计算绑定,包含所有必需的绑定、配置、API,以及程序在 Kubernetes、容器服务,乃至无服务功能(如 AWS Lambda)等计算平台中运行所用的协议。多数情况下,这些绑定对内部架构是透明的,配置更多是为运维团队而非开发所用。容器抽象目前是最广为人知的应用计算绑定“API”。

  • 集成绑定,覆盖范围非常广,从除计算绑定外的其他绑定,到应用的外部依赖关系。云服务同样利用这类绑定与应用交互,常见形式是通过定义完善的 HTTP “API”或专门的消息和存储访问协议,如 AWS S3、阿帕奇卡夫卡、Redis API 等等。集成绑定没有运行时绑定的透明度,开发者也需要实现额外的相关逻辑,如重试、TTL、延时、死信队列(DLQ)等等,并将其与应用的业务逻辑相绑定。

 

云上运行的应用会通过这些绑定消费其他服务,下面让我们这些绑定背后究竟都是些什么。

计算绑定


从理论上来说,所有应用程序对运维团队而言都是需要在计算平台上操作的黑盒单元。计算绑定是用于管理应用在 Kubernetes、AWS Lambda 及其他服务平台上的生命周期。这类绑定均是规范化,以配置集合加上应用与其所运行的平台间交互的 API 的形式进行定义。多数交互都是对应用透明的,只有少数 API 需要开发者自行实施,如健康端点和指标 API。这是目前 CNCF 对此的定义,也是“云原生”概念所囊括的范围,开发者只需实现云原生应用,就能将其绑定在云计算平台上运行。

 


图四:应用与平台的计算绑定

 

为让云平台上的运行更为可靠,应用必须在规范到最佳实践等多个层面与平台绑定。这一过程是通过一系列业界标准规范的实现的,如容器 API 和指标 API、基于普罗米修斯(Prometheus)的健康端点、AWS Lambda 或 AWS ECS 等云供应商规范。此外,还有云原生的最强技术和共享知识,如健康检查、部署策略和安置政策。让我们再看看目前最常见的计算绑定方式。

 

资源需求


无论是微服务还是功能,应用总会对 CPU、内存和存储等资源有所需求。根据所用的平台不同,资源的定义也会不同。举例来说,Kubernetes 上 CPU 和内存是通过请求和限制定义的,而 AWS Lambda 则是由用户指定运行时需要分配的内存大小和对应 CPU。不同平台对存储的处理方式也是各异,Kubernetes 使用短期存储和卷,而 Lambda 则提供短期资源抓取和基于亚马逊 EFS 挂载的持久存储。

 

生命周期钩子


由平台管理的应用程序通常需要对重要的生命周期事件有感知。举例来说,Kubernetes 中的概念(如容器初始化)和钩子(如容器启动后钩子 PostStart 和容器结束前钩子 PreStop)就可以让应用对这些事件做出反应。同理,Lambda 的扩展 API 也能让应用处理初始、调用、关闭阶段。其他处理生命周期事件的方式包括脚本封装或针对特定语言的运行时修改选项(比如 JVM 的关闭钩子)。这些机制为平台与应用程序之间形成协议,使其能够响应并管理自身的生命周期。

 

健康检查


健康探针是平台用于监测应用程序健康状况并按需采取对应行动(如重启应用程序)的方式。虽然出于请求短暂的生命周期,Lambda 函数没有健康探针,但容器化应用程序和 Kubernetes、AWS EKS,GCP 云运行等协调器却可以在其定义中涵盖健康探针,让平台上的应用运行更为顺利,出现问题时也能及时采取行动。

 

部署和置放策略


在获得所需资源后,计算平台可以开始管理应用程序的生命周期了。若想在不破坏业务逻辑完整性的前提下管理生命周期,平台必须要能意识到扩展的限制所在。部分程序只会是单体程序,比如,平台需要维护事件处理的顺序,且不能将其扩展超过一个实例。其他有状态应用可能受法定人数(Quorum)驱动且需要维持指定数量的最小实例,函数才能正常运行。再有,无状态函数可能会倾向于快速扩展以解决负载中不断增长的额峰值。一旦确定了应用程序的扩展方式,平台便能控制应用程序实例的启动和终止。

 

计算平台同样提供包括滚动、蓝绿、金丝雀、一次性等多种部署策略,用于控制服务的更新顺序。除了部署顺序外,平台可能还支持用户指定置放策略。比如 Kubernetes 提供标签、污点(Taint)、容忍度、亲和性、反亲和性等选项,而 Lambda 则允许用户在区域置放和边缘置放类型中进行选择。这些平台的偏好选择确保了应用程序的部署,且与预期合规性和性能要求相符。

网络流量


将低层级网络流量导向服务实例同样是计算平台的责任之一。平台所负责处理的部署顺序、置放,以及自动扩缩容都会影响流量向服务实例的引导。健康检查在流量管理中也发挥着作用,如 GCP 云运行和 Kubernetes 中的就绪检查。通过处理这些任务,计算平台能够协助确保流量是高效且有效地路由到适当的服务实例。

监测与报告


任何用于分布式应用程序的计算平台都必然以日志、指标、跟踪的形式提供深入的应用洞察。如今,在当前领域中也有了约定俗成的标准:日志最好为结构化格式,如 JSON 或其他业界特定标准。计算平台通常会收集日志或提供特殊日志清理和分析服务的访问扩展点。比如 Kubernetes 上的 DaemonSet、Lambda 的监控合作伙伴扩展、Vercel 的边缘函数日志 Drainer。计算平台必须要能支持指标、跟踪数据的收集和分析,才能针对分布式应用程序的性能和行为提供全面的洞察力。业界标准中有许多处理这类数据的格式和工具,如普罗米修斯的指标、OpenTelemetry(OTEL)的跟踪。计算平台或提供内置数据收集和分析工具,或提供扩展点允许专门服务访问这类数据。计算平台应支持任何细粒度(微服务或功能)或位置(边缘与否)的代码,对日志、指标、跟踪数据进行捕捉,并导出至其他优秀的云服务中,如 HoneycombDataDogGrafana 等等。 

计算绑定的趋势


计算绑定是对编程语言和应用运行时不可知的,主要为运维团队管理运行时的应用,而非为开发人员实施所用。

 

虽然应用的大小和复杂度随单体应用或函数而不同,但基本都会封装在容器内,具有健康检查端点,实现了生命周期钩子,并有指标暴露。理解计算绑定有助于高效使用任何基于容器的计算平台,无论是企业内部的 Kubernetes 集群,还是 AWS ECS、谷歌云运行、Azure 容器应用等管理型容器服务,基于函数的运行时 AWS Lambda、GCP 函数等等,以及基于边缘运行时的 Vercel 边缘函数、CloudFlare 工作者、Netlify 边缘函数等等。这些开放和事实标准的 API 不仅能协助创建可移植应用程序,还能通过跨云供应商和服务提供方的操作方法和工具,避免被供应商锁定。

集成绑定


另一方面,集成绑定则是供开发人员而非运维团队使用。集成绑定以常见分布式系统的实现区域为中心,如服务调用、事件驱动交互、任务调度,以及有状态工作流协调。协助应用程序通过基于云的中间件形式服务,与专用存储系统及外部系统相连,在本文中我将这些服务统一称作“集成云”。与容器所提供的计算抽象类似,集成云提供了编程语言不可知集成抽象即服务。其基元与用例、应用实现、运行时和计算环境相独立。重试模式DLQ 模式Saga 模式、服务发现、断路器模式等等,都可以通过服务形式在集成云中被消费。

 


图五:应用程序和平台的集成绑定

 

目前尚不存在将所有主要模式都以独立功能形式暴露的纯集成云。早期的云服务可提供部分集成基元作为卡夫卡、Redis 等存储系统的功能,但却很少能有独立使用或与其他功能相结合的。少有的例外情况是 AWS 事件总线(EventBridge)和 Azure 事件网格等服务,允许与同一厂商的多个云服务同时使用,但不能直接使用其他供应商。这个领域的发展如此快速,虽然还有一些例子或空缺,但我相信在未来,这些空白一定能得到填补。应用程序必须与集成云服务相绑定才能运作,并将部分开发者肩头的责任卸载。以下我将介绍集成云服务的主要类型和绑定方面。

集成需求


与应用对资源的要求和对计算平台的部署和置放需求同理,应用也会对特定集成绑定有需求。这些绑定可通过声明性配置传入平台,也可在运行时通过代码交互激活。举例而言,应用程序可使用声明式和程序式订阅 pub/sub 主题。AWS Lambda 函数可以通过配置声明式地订阅数据源,也可以通过客户端库或 SDK,以程序形式向集成平台发送注册或取消注册特定绑定请求。应用程序可订阅 cron 定时任务触发器,激活连接外部系统的连接器,修改配置等等行为,都是在集成云上进行的。

工作流协调


逻辑协调对持久性服务而言不仅是一种极为普遍的需求,还是将其外部化并作为服务消费的主要候选。因此,工作流协调是如今最为知名的集成绑定类型之一。这种服务的常见用途包括:用于服务和业务流程协调的 Saga 模式实现、AWS 编排函数(Step Function)、谷歌有状态函数、Azure 持久函数、谷歌工作流的任务分配等等。在使用这类绑定时,应用程序中的部分编排状态和逻辑被卸载至其他服务中。应用服务内部虽然还有状态和逻辑对状态进行管理,但其他的都放在了外部,比如其他云服务上。这代表了现今应用程序以独立单元的形式设计并操作方式的转变。未来的应用程序可能不仅仅只有数据在外,集成也会被放在外部。随着对集成云采用的不断出现,更多的集成数据和逻辑将会存在于外部。

临时触发器


临时绑定是协调绑定中的一类基于时间的分类,具有单一目标,即根据给定策略在特定时间触发不同服务。类似的例子有:事件总线调度器、谷歌云调度器、Upstash Qstack 服务等等。

事件驱动和消息服务


这类绑定以事件存储形式卸载请求并解耦应用,但其应用如今也越发地不再局限于存储,而是向提供消息处理模式的方向扩展。除了事件存储,这类绑定也为开发者提供了死信队列、重试、延迟交付等各类基元,还有过滤、聚合、重新排序、基于内容的路由、窃听等等消息处理模式。其示例有:Confluent Cloud kSQL、AWS 事件总线、Decodable 数据管线等等。

外部连接器


这类绑定可协助应用连接至外部系统的同时,也可执行数据规范化、错误处理、协议转换、数据转换。示例有:Knative 源导入器、AWS 事件总线连接器、Confluent 云连接器、Decodable 卡夫卡连接器、AWS Lambda 源和目的地。

健康检查


健康检查是计算绑定中不可或缺的一环,健康检查失败通常会致使应用重启。集成绑定同样需要健康检查,但集成绑定中健康检查不会影响应用的运行时,只会告知集成云当前应用是否有能力处理与集成驱动的交互。失败的集成健康检查会中止集成绑定的过程,直至应用恢复健康才会恢复绑定。经常会出现计算和集成绑定使用同一应用端点进行检查,比如 Dapr 的应用健康检查可以临时阻止消费者和连接器将数据推入不健康的应用。

其他绑定


许多其他的绑定类型也可被归为集成绑定。比如自省数据传入应用程序,指类似 Kubernetes 的向下 API 或 Lambda 的环境变量等,通过简单机制将自省数据和元数据注入应用;配置和秘密绑定,指不仅在应用启动时将秘密注入,还可在任何配置更新时都推送至应用之中,如 Hashicorp Vault Sidecar 注入器、Dapr 的配置 API、Kubernetes 的服务绑定规范。此外,不太常见的集成绑定模式还有分布式,提供对共享资源的互斥访问。

 

集成绑定趋势


无论是长期运行的微服务还是短期的功能,容器都在逐渐成为应用程序打包和运行使用中最多最广的可移植格式。不过,集成绑定也可以被划分为不同的问题领域:事件驱动交互、有状态协调和状态访问,在底层存储和使用模式方面各有不同。举例来说,阿帕奇卡夫卡是事件日志的事实标准,AWS S3 API 用于文档访问、Redis 用于键值缓存、PostgreSQL 用于关系型数据访问等等。这些成为标准化的原因在于不断成长的生态系统,其中包含库、工具,以及围绕其所构建的种种服务,保证了相当程度的成熟度、稳定性、未来的向后兼容性。但是,这些 API 本身只局限于存储访问方面,常常需要开发者自行应对应用程序内的分布式系统挑战。随着软件的平价化,集成绑定也逐渐以服务形式可用。越来越多的无服务云服务提供了额外的集成能力,让应用程序可以绑定数据访问之外的东西。

 

在这种模式下,云绑定应用通常在无服务计算基础设施中运行,和云原生基元一样。它与其他无服务的云服务相绑定,用于服务协调、事件处理或同步互动,如下所示:

 


图六:云绑定应用程序的生态系统

 

一项将多数集成绑定和开发者关注的问题统一至开源 API 的项目是 CNCF 的 Dapr。该项目提供了同步的服务调用、有状态的服务协调、异步的事件驱动的交互,以及以 API 为特定技术的连接器。与容器和 Kubernetes 作为计算抽象类似,Dapr 也是外部服务的抽象。此外,Dapr 也提供与底层云服务独立的集成功能,并经常需要在应用层实现,其中就有弹性策略、死信队列、延迟交付、跟踪、细粒度授权等等其他。Dapr 的设计是多边形且可在应用之外运行,在不改变应用内部架构的情况下,让外部依赖关系交换可以更轻松,正如其在六边形架构中描述的一样。虽然 Dapr 主要为开发者实施应用程序而用,不过在引入后 Dapr 也提高了分布式应用程序的可靠性和可观测性,为运维和架构团队提供了整体效益。关于这点更多信息,我将于今年后半年的 QConLondon 大会上讲述“应用为先的云服务如何改变游戏”,欢迎通过线上或线下形式参与。

后云原生应用


云绑定的的出现代表了云原生从单纯解决计算问题到管理应用层需求的进步。随着云服务对应用栈的不断扩展,从基础设施向应用为先的转换,让这一趋势也在加速发展。这点从以开发者为中心的有状态协调、事件驱动应用基础设施、同步交互、基于云的开发和部署环境、无服务运行时等爆炸性云服务发展中也能一窥一二。这种向应用为先的云服务正在催生一种新的应用程序架构,其中越来越多的应用逻辑在云服务中执行。这种应用程序于第三方云服务的融合也让开发者们能将更多的责任卸载,但随之而来的还可能有对灵活性和敏捷性的限制,这些都会是不断变化的需求所必备的能力。为保持应用程序内部和外部架构的独立性,应用与云服务应在开发时以整齐的边界进行解耦,并在运行时使用定义明确的开放 API 和格式深度绑定。与容器和 Kubernetes 为计算提供了开放的 API 一样,我们需要为应用集成抽象提供开放的 API。这会使操作实践和工具以及开发模式、能力和实践具有可移植性和可复用性。


原文链接

What Are Cloud-Bound Applications?


相关阅读:

微软推出Azure Developer CLI公开预览版,帮助开发者加速云应用开发

全新 AWS Auto Scaling – 适用于云应用程序的统一扩展


2023-05-31 08:002385

评论

发布
暂无评论
发现更多内容

专为实时而生 — GreptimeDB 现已在 GitHub 正式开源

Greptime 格睿科技

开源 分布式 云原生 时序数据库 存算分离

哪些前端学习方法对小白比较有用?

小谷哥

惊艳华为PocketS发布会! 杰美特旗下高端品牌决色推出首款“月光宝壳”

科技热闻

Milvus 编译环境演进

Zilliz

c++ Python Milvus cmake 编译环境

架构--模块5

李某人

架构训练营 #架构训练营

鼎医信息加入PolarDB开源数据库社区

阿里云数据库开源

阿里云 polarDB PolarDB-X 阿里云数据库 PolarDB for PostgreSQL

豆瓣评分9.8!阿里内部的分布式架构手册让多少人突破了瓶颈?

程序知音

Java 分布式 java架构 java架构师 后端技术

5 步!用阿里云 Serverless 搭建高质量的图片压缩工具

阿里巴巴云原生

阿里云 Serverless 云原生

极客时间运维进阶训练营第四周作业

好吃不贵

web前端培训上海学习好吗

小谷哥

一文彻底搞懂前端缓存机制

hellocoder2029

JavaScript

用javascript分类刷leetcode3.动态规划(图文视频讲解)

Geek_07a724

JavaScript LeetCode

大数据培训学习后,就业不好就业

小谷哥

java学习后该怎么培养自主学习能力

小谷哥

「推荐收藏」提高组件库Level必做好这六件事

GFE

前端 组件库

pytorch实现空洞卷积+残差网络实验(torch实现

Studying_swz

深度学习 11月月更

深入剖析nodejs中间件

coder2028

node.js

微博评论高可用高性能计算架构设计

Jack

架构实战训练营9期

5 分钟教你搭建「视频动作分类」系统

Zilliz

人工智能 计算机视觉 Towhee 视频动作分类

自助客户服务页面|从To B产品流量获取到客户服务体验上升

Baklib

深入nodejs的event-loop

coder2028

node.js

Java Web(十二)Vue&Element

浅辄

Vue javaWeb 11月月更

web前端培训学习需要注意什么

小谷哥

OpenI启智社区2022年度优秀项目及开发者申报通知

OpenI启智社区

开源社区 优秀项目 优秀开发者 OpenI启智社区

一比一手写迷你版vue,彻底搞懂vue运行机制

hellocoder2029

一文读懂Js中的this指向

hellocoder2029

JavaScript

前端leetcde算法面试套路之双指针

js2030code

JavaScript LeetCode

复杂组合逻辑电路

二哈侠

Verilog 11月月更 74LS138 译码器

深入理解Node.js的进程与子进程

coder2028

node.js

JavaScript刷LeetCode拿offer-位运算

Geek_07a724

JavaScript LeetCode

融云全球社交泛娱乐洞察,「视频社交」为什么好赚钱,难出圈?

融云 RongCloud

视频社交

云绑定应用:实现业务逻辑,减轻开发者负担_服务革新_InfoQ精选文章