购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

第0章
导论

在导论中,你将了解到API的基础知识以及它们在架构过程中的潜力。我们将提供一个轻量级的API定义,并介绍其在进程内部和外部的使用。为了展示API的重要性,我们将介绍一个会议系统案例研究,这是一个贯穿全书并将逐步演进的实例。进程外的API让你跳出简单的三层架构,我们将通过介绍流量模式及其重要性来说明这一点。此外,我们将概述案例研究的各个步骤,以便你直接跳到感兴趣的领域。

为了介绍API及其相关生态系统,我们将使用一些重要工具。我们将使用C4模型图表( https://c4model.com )介绍案例研究,并重新审视其方法背后的具体逻辑。你还将了解到架构决策记录(ADR)的使用以及在软件生命周期中给出明确决策的价值。在导论的最后,我们会对ADR指南进行概要介绍——这将帮助你根据不同的情况做出正确的决策。

0.1 架构之旅

任何长途旅行的人都不可避免地会问自己一个问题(可能是一再地):“我们到了吗?”最开始询问时,你会查看GPS或路线规划工具,并给出一个估计值,希望途中不会遇到任何延误。同样,构建基于API的架构对开发人员和架构师来说可能是一个复杂的旅程,即使有一个架构导航系统,但你的目的地是哪里呢?

架构是一段没有终点的旅程,你无法预测技术和架构方法会如何变化。例如,你可能无法预测到服务网格技术的使用会变得如此广泛,而一旦你了解了它的能力,就可能会考虑用其来演进现有的架构。影响架构变化的不仅是技术,新的业务需求和约束也推动着架构方向的变化。

增量价值交付并结合新兴技术的最终效果导致了演进架构的概念。演进架构是一种逐步改变架构的方法,重点是具备快速变化的能力,并降低负面影响的风险。在这个过程中,我们要求你记住以下关于API架构的建议:

尽管架构师希望能够对未来进行战略规划,但不断变化的软件开发生态系统使这一点变得困难。既然无法避免变化,我们就需要利用它。

——Building Evolutionary Architectures (由Neal Ford、Rebecca Parsons和Patrick Kua合著,O'Reilly出版)

在许多项目中,API是会随着更多系统和服务的集成而演进的。大多数开发人员构建的服务都专注于单一功能,而没有从消费者的角度考虑更广泛的API重用。

API优先设计是一种开发人员和架构师以消费者为中心考虑其服务的功能的方法,并据此设计出API。API的消费者可以是移动应用程序、另一个服务,甚至是外部客户。在第1章中,我们将探究支持API优先方法的设计技术,并了解如何构建能经受住各种变化的API,为更多的消费者群体提供价值。

好消息是,你可以从任何时间点开启基于API的架构之旅。如果你负责现有的技术仓库,我们将向你展示如何演进你的架构,以促使你在平台中使用API技术。另外,如果你很幸运,开始工作于一个新的项目,我们将根据多年的经验分享采用基于API的架构的好处,同时强调决策中的关键因素。

0.2 API简介

在软件架构领域,有些术语非常难以定义。例如,API(应用程序编程接口),这个概念最早出现在大约80年前。那些存在了相当长时间的术语最终会被过度使用,并在不同的问题领域具有多个含义。我们认为API的含义如下:

●API代表底层实现的抽象。

●API由一份规范来定义,该规范引入了类型。开发人员需要能理解这些规范并使用工具以多种语言生成代码来实现API消费者(使用软件来调用API)。

●API具有定义明确的语义或行为,以有效地模拟信息的交换。

●有效的API设计使得我们可以将其扩展给客户或第三方,以实现业务集成。

广义上说,API根据调用方式可以划分为进程内以及进程外两个类别。这里所指的进程是指操作系统(OS)进程。例如,从一个Java类调用另一个Java类中的方法是一个进程内的API调用,因为调用的处理和调用的发起处于同一个进程。使用HTTP库的.NET应用程序调用外部类似REST的API是一个进程外的API调用,因为调用是由一个额外的外部进程而不是调用发起方的进程处理的。通常,进程外的API调用涉及在网络上传输的数据,可能是本地网络、虚拟私有云(VPC)网络或互联网。我们将重点关注后一种类型的API,然而,架构师经常会遇到将进程内API重构为进程外API的要求。为了演示这个概念(以及其他许多概念),我们将创建一个实际运行的案例研究,该案例研究将贯穿整本书并逐步演进。

0.3 真实示例:会议系统案例研究

我们选择了一个会议系统作为我们的案例研究模型,因为这个领域容易被理解,同时也提供了足够的复杂性来建模一个演进架构。图0-1在顶层展示了会议系统,让我们能够设定正在讨论的架构的上下文。这个系统被外部客户用于创建参会者账户,查看可用的会议场次,并预约参会。

图0-1:C4会议系统上下文图

让我们放大到图0-2中的会议系统方框。展开会议系统可以提供更多关于其主要技术构建模块的细节。客户与Web应用程序进行交互,该应用程序调用会议应用程序的API。会议应用程序使用SQL查询后端数据存储。

图0-2:C4会议系统容器图

图0-2揭示了从API的角度来看,最有趣的功能位于会议应用程序容器内。图0-3放大了这个特定的容器,让你可以探索其静态结构和交互方式。

当前系统涉及四个主要组件和数据库。API控制器面对来自用户界面的所有传入流量,并决定将请求路由到系统的哪个位置。该组件还负责把网络格式的数据包转换为代码中的对象或表示形式。从进程内路由和充当连接点或前端控制器模式的角度来看,API控制器组件非常有趣。对于API请求和处理,这是一个重要的模式,所有请求都经过控制器,它决定请求的去向。在第3章中,我们会探讨将控制器从进程中剥离的可能性。

参会者、预订和会议场次 组件负责将请求转换为查询语句,并在进程外执行针对数据库的SQL操作。在现有架构中,数据库是一个重要的组件,可能用来强制保障数据间的关系,例如预订和会议场次之间的约束。

图0-3:C4会议系统组件图

既然已经深入足够的细节,让我们重新审视一下案例研究中的API交互类型。

0.3.1 会议案例研究中的API类型

在图0-3中,从Web应用程序到API控制器的箭头代表一个进程外调用,而从API控制器到参会者组件的箭头则是一个进程内调用的示例。在会议应用程序边界内的所有交互都是进程内调用的示例。进程内调用是由用于实现会议应用程序的编程语言明确定义和限制的。调用在编译时是安全的(交换机制的执行条件在编写代码时就已经确定)。

0.3.2 改进会议系统的原因

会议系统使用目前的架构方法多年来一直运行良好,然而会议组织者提出了三个改进要求,这些要求推动了架构的变化:

●会议组织者希望构建一个移动应用程序。

●会议组织者计划将系统推广到全球,每年举办数十个会议,而不是仅限于一个。为了促进这种扩展,他们希望与外部的征稿(Call for Paper,CFP)系统集成,以管理演讲者信息及他们的会议演讲申请。

●会议组织者希望停用私有数据中心,改为在具有全球覆盖范围的云平台上运行会议系统。

我们的目标是改进会议系统使其能够支持新需求,同时不影响现有的生产系统,也不需要一次性重写所有内容。

0.3.3 从分层架构到API建模

这个案例研究的起点是一个典型的三层架构,由用户界面(UI)、服务器端处理层和数据存储组成。要开始讨论演进式架构,我们需要一个模型来思考组件如何处理API请求。这个抽象的模型将能同时适用于公有云、运行在数据中心内的虚拟服务器以及这两者混合的架构。

流量的抽象将使我们能够考虑API消费者和API服务之间的进程外交互,API服务有时也称为API生产者。对于面向服务的架构(SOA)和基于微服务的架构等架构方法来说,模拟API交互的重要性是至关重要的。了解API流量和组件之间的通信方式将确保能够享受降低耦合的好处,避免产生维护上的噩梦。

数据中心工程师使用流量模式来描述数据中心内部和底层应用程序之间的网络数据交互。在API层,我们使用流量模式来描述数据在不同应用程序之间的流动。在本书中,我们指的是应用程序层和API层的流量模式。

0.3.4 案例研究:演进步骤

为了开始考虑流量模式类型,在我们的案例研究架构中,采取一个小的演进步骤会很有帮助。在图0-4中,我们已经对参会者组件进行了重构,将其变成了一个独立的服务,而不是原有会议系统中的一个包或模块。现在,会议系统有两个数据流:参会者与原有会议系统之间的交互,以及原有会议系统与参会者系统之间的交互。

图0-4:C4会议系统上下文——演进步骤

南北向流量

在图0-4中,参会者与原有会议系统之间的交互被称为南北向流量,它代表了一个入口流量。参会者正在使用UI(用户界面),通过互联网向原有会议系统发送请求。这代表了我们网络中公开暴露的一个点,其将被UI访问 。这意味着任何处理南北向流量的组件在允许流量通过系统之前,必须对参会者身份进行具体检查,并包含适当的质询。第7章将详细介绍如何保护南北向API流量的安全性。

东西向流量

原有会议系统与参会者服务之间的新交互引入了系统内部的东西向流量。东西向流量可以被视为应用程序组内的服务与服务之间的通信方式。大部分东西向流量,尤其是如果源于基础设施内部,那么可以给予一定程度的信任。尽管我们可以信任流量的来源,但仍然有必要考虑保护东西向流量的安全性。

0.3.5 API基础设施和流量模式

在基于API的架构中,有两个关键的基础设施组件,对于控制流量起着重要作用。控制和协调流量通常被称为流量管理。一般来说,南北向流量由API网关控制,这是第3章的重点内容。

东西向流量通常由类似Kubernetes或服务网格的基础设施组件处理,这是第4章的重点内容。类似Kubernetes和服务网格的基础设施组件使用网络抽象来路由到服务,要求服务在受控环境中运行。在某些系统中,东西向流量由应用程序自身管理,并通过服务发现技术来定位其他系统。

0.3.6 会议系统案例研究的路线图

在本书中,你将看到系统在以下方面的改进或技术应用:

●第1章中,你将探索参会者API的设计和规范。我们还将介绍版本控制的重要性以及如何设计数据交换方法以提高参会者API的性能。

●第2章中,你将探索契约和组件测试,以验证参会者服务的行为。你还将了解到Testcontainers如何帮助进行集成测试。

●第3章中,你将研究如何使用API网关将参会者服务提供给消费者。我们还将演示如何在Kubernetes上使用API网关来演进会议系统。

●第4章中,我们将使用服务网格将原有会议系统中的议程功能进行重构。你还将了解到服务网格如何帮助路由、可观测性和安全性方面的工作。

●第5章中,我们将讨论功能开关和它如何帮助演进会议系统并避免耦合的部署和发布。你还将探索会议系统中发布建模的方法,并演示如何使用Argo Rollouts来管理参会者服务。

●第6章中,你将探索如何进行威胁建模并防范参会者服务遭受OWASP里提到的攻击。

●第7章中,你将研究身份验证和授权以及如何在参会者服务中实现这些功能。

●第8章中,你将研究如何建立参会者服务的领域边界以及如何利用不同的服务模式。

●第9章中,你将研究云服务以及如何用平台化改造策略将参会者服务迁移到云端。

案例研究和规划清晰的路线图要求我们使架构变化可视化并记录决策。这些是帮助解释和计划软件项目变化的重要文档。我们认为C4图表和架构决策记录(ADR)是能够清晰记录变化的方法。

0.4 使用C4图表

在介绍案例研究的一部分内容中,我们揭示了C4模型中的三类C4图表( https://c4model.com )。我们相信C4是向各种利益相关者传达架构、上下文和交互的最佳文档标准。也许你会想到UML(Unified Modeling Language,统一建模语言)呢?UML是一个用于传达软件架构的强大语言。主要问题之一是,大多数UML提供的功能对架构师和开发人员来说难以记忆,人们很快就会回到方框/圆圈/菱形的表示方式。在深入讨论技术内容之前,理解图表的结构变得非常困难。如果有人不小心使用了永久性标记笔而不是可擦写笔,许多图表只会被记录在项目历史中。C4模型提供了一组简化的图表,可以作为项目架构在不同层次上的指南。

0.4.1 C4上下文关系图

图0-1使用了C4模型中的上下文图来表示。该图的目的是为所有人提供背景信息。许多架构讨论直接深入底层细节,而忽略了建立高层级的沟通渠道。想象一下画出一个错误的系统上下文关系图的后果——准确的总结可能会节省数月的工作时间来纠正误解。

0.4.2 C4容器图

尽管图0-1提供了会议系统的整体情况,但容器图可以帮助描述架构中主要部分的技术细节。在C4中,容器被定义为“为了使整个系统正常运行而需要运行的东西”(例如,会议数据库)。容器图是技术性的,是在更高级别的系统上下文图的基础上建立起来的。图0-2是一个容器图,记录了客户与会议系统交互的详细信息。

图0-2中的会议应用容器被简单地记录为软件。通常,C4容器会提供更多关于容器类型的详细信息(例如,Java Spring应用程序)。然而,在本书中,我们将避免涉及技术细节,除非它有助于演示特定的解决方案。API和现代应用程序的优势在于,具体解决方案有很大的灵活性。

0.4.3 C4组件图

图0-3中的C4组件图有助于定义每个容器内的角色和责任,以及内部交互。如果需要查询容器的详细信息,这个图表非常有用,它还提供了一个非常有用的代码库地图。想象一下第一次开始一个新项目的时候:浏览一个自我文档化的代码库是方法之一,但是要一览全貌可能很困难。组件图揭示了构建软件所使用的语言/技术栈的细节。为了保持技术无关性,这里我们使用了术语“包/模块”。

0.5 使用架构决策记录

作为开发人员、架构师,甚至是普通人,我们都曾处于这样的境地,想着过去的自己并发问:“他们当时到底在想什么?”如果你曾经驾车行驶在英国利兹和曼彻斯特之间的M62高速公路上,你可能会对这条高速公路的建设感到困惑。当驶上这条三车道的高速公路时,它开始与旁边的逆向车道相偏离,直到最后斯科特霍尔农场出现在车道之间,大约有15英亩(91.0545亩)农田。根据当地的传说,这块地的拥有者固执己见,拒绝搬迁或交出土地,所以工程师干脆在农场周围修建了高速公路 。50年后,一部纪录片揭示了真正的原因是土地下面存在地质断层,这意味着必须以这种方式修建高速公路。当人们猜测为什么某件事会以特定的方式进行时,你可以预料到各种传言、段子和批评都会出现。

在软件架构中,我们将面临许多需要考虑的约束条件,因此确保我们的决策被记录并可查阅是非常重要的。ADR(架构决策记录)有助于明确记录软件架构中的决策过程。

在项目的整个生命周期中,最难追踪的事物之一是某些决策背后的动机。新加入项目的人可能会对一些过去的决策感到困惑、迷惑、高兴或愤怒。

——ADR概念的创始人Michael Nygard

ADR有四个关键部分组成:状态、背景(context)、决策和影响。ADR在创建时处于建议状态,并通常会根据讨论结果被接受或拒绝。也有可能决策在以后被新的ADR取代。背景有助于设定场景并描述问题或决策的范围。尽管在ADR之前创建博客文章,然后从ADR中进行链接有助于团队跟踪工作进展,但背景并不局限于一篇博客文章或详细描述。决策清楚地阐明了你计划做什么以及如何做。所有决策在架构上都会造成影响或带来取舍,有时错误的决策可能导致高昂的代价。

在评审ADR时,重要的是看你是否同意ADR中的决策,或者是否有其他替代方案。事先未考虑到的替代方案可能导致ADR被拒绝。被拒绝的ADR具有很大的价值,大多数团队选择保留原始的ADR,以捕捉视角的变化。当ADR被展示给核心成员查看、评论并获得认可时,其发挥了最大功效。

我们经常被问到一个问题:团队在什么时候应该创建ADR?确保在ADR之前已经进行了讨论,并且记录是团队集体思考的结果,这是非常有用的。将ADR发布给其他团队可以获得外部的反馈机会。

0.5.1 参会者演进ADR

在图0-4中,我们决定对会议系统架构做出改变。这是一个重大的变化,值得进行ADR。表0-1是一个示例ADR,可由负责会议系统的工程团队提出。

表0-1:将参会者组件从原有会议系统中分离的ADR001

ADR中的某些影响十分重要,需要进一步讨论。我们将在后面的章节中继续讨论其中的一些影响。

0.5.2 精通API:ADR指南

在本书中,我们将提供ADR指南,以帮助收集在我们所涵盖的主题上做决策时需要问的重要问题。针对基于API的架构做出决策可能非常困难,在许多情况下答案是“取决于具体情况”。为了不是没有上下文地说这句话,ADR指南将帮助描述它取决于什么,并帮助你做出决策。如果你面临特定的挑战,那么ADR指南可以作为参考点,供你回头查看或者提前阅读。表0-2概述了ADR指南的格式以及你应该期望它能解决什么问题。

表0-2:ADR指南——格式

0.6 小结

在导论中,我们给出了一个案例研究,并介绍了将用来演进API驱动架构的方法,作为之后讨论的基础:

●架构变化永无止境,API可以在其中发挥重要作用。

●API是实现的抽象,可以是进程内或进程外的。通常,架构师发现自己需要将API演进为进程外的形式,本书的重点就在于此。

●会议系统案例研究是为了描述和解释概念。在导论中,你已经看到了一个小的演进步骤,将参会者服务拆分出来以满足即将到来的业务需求。

●你已经看到了前三个级别的C4图表及其在分享和传达架构信息方面的重要性。

●ADR为决策提供了有价值的记录,在项目的整个生命周期中不仅有当前的价值,也有回溯的价值。

●你已经看到了ADR指南的结构,这将在整本书中用于帮助实现决策。

在决定将参会者服务从会议系统中拆分出来后,我们现在将探讨设计和规范参会者API的方法。 oDCwkdvF1yYyFwlorFmhfrwBReHf5O0djv+1jU99VHyzaW0fi1Bjos31nuIpS7Re

点击中间区域
呼出菜单
上一章
目录
下一章
×