1.7.2 基于服务架构的云原生应用
在本书中,我们将会按照基于服务的架构来设计和构建云原生应用。
我们的主要工作单元是服务,它能够以不同的方式与其他服务交互。按照Cornelia Davis在Cloud Native Patterns(Manning, 2019年)一书中所提出的划分方式,我们可以在这种架构中识别出两个元素,分别是服务和交互。
■ 服务:一个能够向其他组件提供任意类型的服务的组件。
■ 交互:为完成系统的需求,服务之间所产生的通信。
服务是一个非常通用的组件,它们可以是任何东西。根据是否存储任意类型的状态,我们可以将其区分为应用服务(无状态)和数据服务(有状态)。
图1.14展示了云原生架构的元素。用来管理图书馆库存的应用应该是应用服务。存储图书信息的PostgreSQL数据库应该是数据服务。
1.应用服务
应用服务是无状态的,负责实现各种类型的逻辑。它们不必像微服务那样遵循特定的规则,只需要具备我们在前文所述的所有云原生属性即可。
最重要的是,在设计每个服务的时候,我们要考虑到松耦合和高内聚。服务应该尽可能独立。分布式系统是很复杂的,所以在设计阶段要格外小心。增加服务的数量也会导致问题数量的增加。
图1.14 基于服务架构的云原生应用。主要的元素是服务(应用或数据),它们会以不同的方式进行交互
我们可能会开发和维护系统中大多数的应用服务,但也可能会使用云供应商提供的一些服务,如认证和支付服务。
2.数据服务
数据服务是有状态的,负责存储各种类型的状态。状态指的是关闭服务和启动新实例时,应该保存下来的所有内容。
它们可以是像PostgreSQL这样的关系型数据库,像Redis这样的键/值存储,或者像RabbitMQ这样的消息代理。我们可以自己管理这些服务。由于保存状态需要存储,所以这比管理云原生应用更具挑战性,但这能够获得对自己数据的更多控制权。另一个可选方案是使用云提供商提供的数据服务,它将负责管理所有与存储、韧性、可扩展性和性能相关的问题。在后一种方案中,我们可以使用很多专门为云构建的数据服务,如Amazon DynamoDB、Azure Cosmos DB和Google BigQuery。
云原生数据服务是一个非常有吸引力的话题,但在本书中,我们将主要处理应用。与数据有关的问题,如集群、复制、一致性或分布式事务,在本书中不会有太多的详细阐述。尽管我很想这样做,但这些话题应该有专门的图书来充分地介绍。
3.交互
云原生服务需要相互沟通以满足系统的需求。如何进行通信将影响系统的整体属性。例如,选择请求/响应模式(同步的 HTTP 调用)而不是基于事件的方法(通过 RabbitMQ 实现消息流)会为应用带来不同的韧性。在本书中,我们会使用不同类型的交互,并学习它们的差异,以及每种方式适合什么样的场景。