冠军

导航

Dapr-3: 从 20000 英尺之上俯瞰 Dapr

第 3 章 从 20000 英尺之上俯瞰 Dapr

Dapr at 20,000 feet | Microsoft Docs

在第 1 章中,我们讨论了分布式微服务应用的吸引力。但是,我们也指出了它会急剧增加架构和操作的复杂性。记住这一点,这样问题就变成了你如何有你的蛋糕,与如何吃掉它。也就是说,你如何既能得到分布式架构敏捷的优势,又能最小化它的复杂性。

Dapr,或者 分布式应用程序运行时 ,就是一种构建现代分布式应用程序的方式。

从一个原型开始演进为高度成功的开源项目。它的赞助商 Microsoft,与客户和开源社区紧密合作进行设计和构建 Dapr。Dapr 项目带领开发者从头开始解决开发分布式应用程序的艰难挑战。

本书从 .NET 开发者的角度来看待 Dapr。在本章中,你将建立对 Dapr 的概念理解,以及它是如何工作的。随后,我们提供动手实验来指导你如何在你的应用程序中使用 Dapr。

想象一下,你正在从 20000 英尺高空的飞机上,从窗口往外巡视,广阔的大地展现在眼前。让我们对 Dapr 做同样的事情。将你自己带入 20000 英尺高度,你会看到什么?

Dapr 和它解决的问题

Dapr 直面现代分布式应用程序的巨大挑战:复杂性

考虑一个可插拔组件的架构,Dapr 极大简化了分布式应用程序背后的管道。它提供了 动态胶水 从 Dapr 运行时将你的应用程序绑定到架构的功能上。

考虑需要将你的一个服务状态化?你需要设计什么。你可能需要编写定制化的代码来处理状态存储,例如 Redis 缓存。但是,Dapr 提供了开箱即用的状态管理功能。你的服务调用 Dapr 的状态管理 构建块,它就可以魔术般的通过 Dapr 组件配置 yaml 文件来绑定到状态存储 组件。Dapr 提供了一系列预构建的状态管理组件,包括 Redis。基于该模型,你的服务将状态管理代理给 Dapr 运行时。你的服务不需要 SDK 库,或者直接引用底层的组件。甚至你可以变更你的状态存储,例如从 Redis 变成 MySQL 或者 Cassandra,而不需要修改代码。

图 2-1 展示从 20000 英尺之上俯瞰的 Dapr

图 2-1

在图顶部的行中,注意 Dapr 对流行的开发平台提供了语言特定的 SDK。Dapr v1.0 支持包括:Go、Node.js、Python、.NET、Java 和 JavaScript。本书关注于 Dapr 的 .NET SDK,它也提供了对 ASP.NET Core 集成的直接支持。

虽然语言特定的 SDK 扩展了开发者的体验,Dapr 本身是平台无关的。在底层,Dapr 的编程模型通过标准的 HTTP/gRPC 通讯协议提供其能力。任何编程平台可以通过原生 HTTP 和 gRPC API 调用 Dapr 。

位于图中间的蓝色框中表示 Dapr 提供的构建块,其中的每个提供了你的应用程序可以使用的分布式应用程序的功能。

图的底部重点提示了 Dapr 的移植性,它可以跨越多种环境运行。

Dapr 架构

此时,飞机盘旋在 Dapr 之上,降低高度,使你可以更近的查看 Dapr 是如何工作的。

构建块

从这个新的视角,你可以看到 Dapr 构建块的细节。

一个构建块封装了一个分布式架构的功能。可以通过 HTTP 或者 gRPC API 来访问该功能。图 2-2 展示了 Dapr v1.0 提供的构建块。

图 2-2 Dapr 构建块

下表中说明了每个构建块提供的基础架构服务

构建块 说明
状态管理 State Management 支持长时间运行的有状态服务的上下文信息
服务调用 Service Invocation 直接调用,使用平台无关协议和众所周知的端点进行安全服务调用,
发布于订阅 Publish/Subscribe 在服务之间,实现安全、可扩展的发布/订阅消息
绑定 Bindings 基于双向绑定通讯,从外部资源触发的事件来触发代码
可见性 Observability 监控和测量跨网络服务的消息调用
密钥 Secrets 安全访问外部密钥存储
执行人 Actor 通过可重用的执行人对象封装逻辑与数据

构建块从你的服务中抽象了实现分布式应用该程序功能的实现。

构建块调用 Dapr 组件,Dapr 组件提供实例化每种资源的实现。你的服务中的代码只需要关心构建块。它不依赖外部的 SDK 或者库。 Dapr 为你处理管道问题。每个构建块都是独立的。你可以在你的应用程序中使用其中一个,或者某些,甚至全部。作为附加值,Dapr 构建块基于业界的最佳实践包括易于理解的可观察性。

在随后的章节中,对于每个构建块,我们提供详细说明和代码示例。此时,飞机会更加降低高度,从新的视角,现在你可以更近的观察 Dapr 组件层。

组件

尽管构建块提供了 API 来调用分布式应用程序功能,Dapr 组件提供实现该功能的具体实现。

考虑 状态存储 组件,它提供了统一的方式来管理 CRUD 操作,而不需要对你的服务代码进行任何修改。你可以在任何下列 Dapr 状态组件之间切换:

  • AWS DynamoDB
  • Aerospike
  • Azure Blob Storage
  • Azure CosmosDB
  • Azure Table Storage
  • Cassandra
  • Cloud Firestore (Datastore mode)
  • CloudState
  • Couchbase
  • Etcd
  • HashiCorp Consul
  • Hazelcast
  • Memcached
  • MongoDB
  • PostgreSQL
  • Redis
  • RethinkDB
  • SQL Server
  • Zookeeper

每个组件通过统一的状态管理接口提供其实现:

type Store interface {
   Init(metadata Metadata) error
   Delete(req *DeleteRequest) error
   BulkDelete(req []DeleteRequest) error
   Get(req *GetRequest) (*GetResponse, error)
   Set(req *SetRequest) error
   BulkSet(req []SetRequest) error
}

提示:

Dapr 运行时,以及所有的 Dapr 组件都使用 Go 语言开发。Go 是开源社区的流行语言,验证了 Dapr 的跨平台承诺。

也许你使用 Azure Redis Cache 作为你的状态存储。使用如下配置进行设置:

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: statestore
  namespace: default
spec:
  type: state.redis
  version: v1
  metadata:
  - name: redisHost
    value: <HOST>
  - name: redisPassword
    value: <PASSWORD>
  - name: enableTLS
    value: <bool> # Optional. Allowed: true, false.
  - name: failover
    value: <bool> # Optional. Allowed: true, false.

在 spec 配置节,配置 Dapr 使用 Redis Cache 作为状态管理。该配置节也包含组件特定的元数据。在此例中,你还可以使用它来配置其它的 Redis 设置。

在随后的时间里,应用程序准备发布。对于产品观景,你可能希望将状态管理切换为 Azure STorage。Azure Table Storage 提供可负担和高持久的状态管理能力。

在本文撰写的时候,Dapr 提供了下列组件类型:

组件 说明
服务发现 Service discovery 被服务调用构建块使用,以便与宿主环境集成,提供服务到服务的发现。
状态 State 对众多状态存储实现提供统一的访问接口
发布/订阅 Pub/Sub 对众多消息总线实现提供统一访问接口,
绑定 Binding 基于双向绑定通讯,从外部资源触发的事件来触发代码
中间件 Middleware 支持自定义的中间件插入到请求处理管线中,在请求或者响应的中调用附加的操作。
密钥存储 Secret store 对外部密钥存储提供统一的访问接口,包括 Cloud、Edge、商业、开源服务等。

飞机已经完成了环绕 Dapr 的飞行,一再回顾,你可以看到它是如何连接在一起的。

Dapr 通过 [sidebar 架构](Sidecar pattern - Cloud Design Patterns | Microsoft Docs) 来暴露出构建块和组件。Sidebar 使得 Dapr 伴随你的服务运行在独立的内存和进程中。Sidebar 不是你的服务的一部分,提供了隔离和封装性。但是可以连接到它。该分离使得每个组件可以有自己的运行环境,由不同的编程平台所构建。图 2-4 展示了 sidebar 模式。

图 2-4 Sidebar 模式

该模式被命名为 sidebar,中文称为挎斗,因为它就像三轮摩托的挎斗连接到摩托车上。在上面的图中,注意到 Dapr 是如何连接到你的服务以提供分布的应用能力的。

托管环境

Dapr 拥有跨平台的能力,可以运行在多种不同环境下。这些环境包括:Kubernates,一组虚拟机,或者边缘环境,例如 Azure IoT 等等。

对于本地环境,最容易的方式是使用自寄宿模型。在自寄宿模式下,微服务和 Sidebar 运行在分离的本地进程中,而不需要诸如 Kubernetes 容器调度器。更多信息,可以参考 download and install the Dapr CLI

图 2-5 展示了分别寄宿于独立的内存进程中,通过 HTTP 或者 gRPC 通讯的应用程序和 Dapr。

图 2-5 自寄宿的 Dapr sidecar

默认情况下,Dapr 为 Redis 和 Zipkin 安装 Docker 容器,以提供默认的状态管理和可见性。如果你不希望在本地机器上安装 Docker,可以在自寄宿模型下,不需要任何 Docker 容器运行 Dapr。不过,你必须安装手动安装默认的组件,诸如用于状态管理的 Redis 和 Pub/Sub 组件。

Dapr 可以运行在容器化的环境下,例如 Kubernetes,图 2-6 展示了运行在独立的 side-car 容器中的 Dapr,伴随着应用程序的容器一起位于同一个 Kubernetes 的 Pod 中。

图 2-6 寄宿于 Kubernetes 中的 Dapr sidebar

Dapr 性能考虑

如你所见,Dapr 使用 Sidebar 模式来解耦于你的应用程序与分布式应用程序功能之间的连接。调用某个 Dapr 操作需要至少一次进程外的网络调用。图 2-7 展示了 Dapr 流量模式的示例。

图 2-7 Dapr 的流量模式

请看上图,一个问题是网络延迟和开销影响到每次调用。

Dapr 团队在性能方面投入大量资源。大量的工程工作已经投入到 Dapr 中使得 Dapr 高效。在 Dapr 之间的调用总是使用 gRPC,这提供了更高的性能和更小的二进制负载。在大多数情况下,额外的开销为小于毫秒。

为了增进性能,开发人也可以使用 gRPC 来访问 Dapr 构建块。

gRPC 是现代的,高性能框架,发展了古老的远程调用 RPC 协议。gRPC 使用 HTTP/2 作为传输协议,相比 HTTP RESTFul 提供了显著的性能增加,包括:

  • 多路复用支持,用来在单个连接上发送多个并行的请求,HTTP 1.1 限制在同时只能处理单个请求/响应消息。
  • 双向全双工通讯,同时发送客户端请求和服务器响应
  • 内建的流支持,对于大量数据支持请求和响应异步流

更多内容,可以参考 gRPC overview

Dapr 和服务聚合

对于分布式应用程序,服务聚合是另一个快速演进的技术。

服务聚合是一种可配置的基础架构层,内建处理服务到服务的通讯、弹性、负载均衡、侦测捕获。它将这些问题的处理从服务中移出到服务聚合层中。与 Dapr 类似,服务聚合也遵循 sidebar 架构。

图 2-8 展示了实现服务聚合技术的一个应用程序。

上图展示了消息是如何被 sidebar 代理拦截,这些代理伴随每个服务运行。每个代理可以针对服务配置流量规则。它理解消息,并可以在你的服务之间,以及与外部世界路由消息。

所以,问题变成了:Dapr 是服务聚合吗?

尽管它们都使用 sidebar 架构,但每种技术有着不同的目的。Dapr 提供分布式应用的功能。而服务聚合提供专门的网络基础架构层。

由于它们工作在不同的层级上,它们可以在同一个应用中一起工作。例如,服务聚合可以提供服务之间的网络通讯。Dapr 可以提供应用程序的服务,诸如状态管理或者工作者服务。

图 2-9 展示了同时实现 Dapr 和服务总线技术的一个应用程序

图 2-9 Dapr 与服务聚合一起协同

Dapr online documentation 介绍了 Dapr 与服务聚合的集成。

总结

本章介绍了 Dapr,分布式的应用程序运行时。

Dapr 是由微软支持的开源项目,与客户和开源社区紧密协作。

本质上,Dapr 帮助减少分布式微服务应用程序固有的复杂性。它建立在构建块 API 的概念之上。Dapr 构建块暴露公共的分布式应用功能,诸如状态管理,服务到服务的调用,以及消息的发布/订阅等等。Dapr 组件位于构建块之下,为每个功能提供具体实现。应用程序通过配置文件绑定到各种组件。

在下一章,我们将提供练习,关于如何在你的应用程序中使用 Dapr 的动手指导。

posted on 2022-03-18 15:21  冠军  阅读(102)  评论(0编辑  收藏  举报