Dapr + .NET Core实战(一) 基础概念与环境搭建
什么是Dapr
Dapr 是一个可移植的、事件驱动的运行时,可运行在云平台或边缘计算中。支持多种编程语言和开发框架。
上面是官方对Dapr的介绍。有点难以理解,大白话可以理解为:Dapr是一个运行时,支持在云平台中运行多种语言的应用程序。运行时我们都理解,是应用程序运行依赖的环境,像Java运行时,Python运行时,.NET运行时等,为应用程序的运行提供了环境:垃圾回收,线程管理等。Dapr同样是一个运行时,那他为我们解决了什么呢?我们先来谈下现在软件开发的一些难点。
1.为了承载大并发我们需要用很多中间件,比如rabbitmq,kafka
2.服务间调用会用HTTP或者RPC等不同通信方式
3.保存一些状态数据可能用Redis或者数据库等不同存储
4.保存一些密钥信息可能用Azure Keyvault或者K8S Secrets等不同密钥存储
...
为了解决这些问题,很多开发人员无法专注业务,必须了解很多架构方面的东西,往往很多开发人员希望专注业务,希望平台提供好这些基础设施,不需要花费大量的时间在部署中间件,学习中间件上。并且为了解决这些问题代码中需要集成很多中间件,对代码有很强的侵入性。这就是Dapr所要解决的。 Dapr 将构建微服务应用的 最佳实践 设计成开放、独立和模块化的方式,让你能够使用任意的开发语言和框架构建可移植的应用程序。 每个构建块都是完全独立的,您可以采用其中一个、多个或全部来构建你的应用。为了解决这些问题,Dapr引入了Sidecar架构。
Sidecar架构
Dapr中,每个服务,每个运行的服务都会运行一个Sidecar,而Dapr的服务间通信,服务与各中间件的通信都通过Sidecar来通信,而我们的代码里只需要调用Dapr提供访问Sidecar的API,即可完成服务间通信,状态存储,服务监控等功能,完美地解决了传统架构中的代码侵入性问题。
工作原理
Dapr提供了七大核心组件来支撑应用程序的无侵入式分布式开发。
1.服务调用
通过服务调用,应用程序可以使用 gRPC 或 HTTP 这样的标准协议来发现并可靠地与其他应用程序通信。
Dapr 采用边车(Sidecar)、去中心化的架构。 要使用 Dapr 来调用应用程序,请在任意 Dapr 实例上使用 invoke 这个API。 sidecar 编程模型鼓励每个应用程序与自己的 Dapr 实例对话。 Dapr 实例会相互发现并进行通信。
-
服务 A 对服务 B 发起HTTP/gRPC的调用。
-
Dapr通过服务名解析组件发现了运行在此Dapr环境中的服务B
-
Dapr 将消息转发至服务 B的 Dapr 边车
注: Dapr 边车之间的所有调用考虑到性能都优先使用 gRPC。 仅服务与 Dapr 边车之间的调用可以是 HTTP 或 gRPC
-
服务 B的 Dapr 边车将请求转发至服务 B 上的特定端点 (或方法) 。 服务 B 随后运行其业务逻辑代码。
-
服务 B 发送响应给服务 A。 响应将转至服务 B 的边车。
-
Dapr 将消息转发至服务 A 的 Dapr 边车。
-
服务 A 接收响应
通过以上步骤我们可以发现,我们只需要调用调用自己的sidecar的invoke方法来调用其他服务即可,比如
localhost:3500/v1.0/invoke/nodeapp.production/method/neworder
2.状态管理
当使用状态管理时,你的应用程序可以利用一些自己构建会很复杂,容易出错的功能,比如:
- 分布式并发和数据一致性
- 批量CRUD 操作
你的应用程序可以使用Dapr的状态管理API,使用状态存储组件保存和读取键/值对,如下图所示。 例如,通过使用HTTP POST可以保存键/值对,通过使用HTTP GET可以读取一个键并返回它的值。
而Dapr的状态存储组件支持可插拔,可以不用改代码而随意替换。
3.发布订阅
发布 / 订阅模式 允许微服务使用消息相互通信。 生产者或发布者 将消息发送至 主题(Topic) ,并且不知道接收消息的应用程序。 这涉及将它们写入一个输入频道。 同样,一个 消费者 将订阅该主题并收到它的消息,并且不知道什么应用程序生产了这些消息。 这涉及从输出频道接收消息。 中间消息代理(intermediary message broker)负责将每条消息从输入频道复制到所有对此消息感兴趣的订阅者的输出频道。 当您需要将微服务解偶时,此模式特别有用。
Dapr 中的发布/订阅 API 提供至少一次(at-least-once)的保证,并与各种消息代理和队列系统集成。 您的服务所使用的特定实现是可插拔的,并被配置为运行时的 Dapr Pub/Sub 组件。 这种方法消除了您服务的依赖性,从而使您的服务可以更便携,更灵活地适应更改。
4.资源绑定
使用绑定,您可以使用来自外部系统的事件或与外部系统的接口来触发应用程序。 此构建块为您和您的代码提供了若干益处 :
- 除去连接到消息传递系统 ( 如队列和消息总线 ) 并进行轮询的复杂性
- 聚焦于业务逻辑,而不是如何与系统交互的实现细节
- 使代码不受 SDK 或库的跟踪
- 处理重试和故障恢复
- 在运行时在绑定之间切换
- 构建具有特定于环境的绑定的可移植应用程序,不需要进行代码更改
5.Actors
actor 模式 阐述了 Actors 为最低级别的“计算单元”。 换句话说,您将代码写入独立单元 ( 称为actor) ,该单元接收消息并一次处理消息,而不进行任何类型的并行或线程处理。
当代码处理一条消息时,它可以向其他参与者发送一条或多条消息,或者创建新的 Actors。 底层 运行时 将管理每个 actor 的运行方式,时机和位置,并在 Actors 之间传递消息。
6.可观测性
Dapr 使用 Zipkin 协议进行分布式跟踪和指标收集。 由于 Zipkin 协议无处不在,许多后端被开箱即用,例如 Stackdriver、 Zipkin、 New Relic 等。 与 OpenTelemetry 收藏器组合,Dapr 可以导出跟踪到许多其他后端,包括但不局限于 Azure Monitor Datadog, Instanca, Jaeger, and SignalFX
Dapr 将 HTTP/GRPC Middleware 添加到 Dapr sidecar。 Middleware 拦截所有 Dapr 和应用程序流量,并自动注入关联ID以跟踪分布式事务。 此设计有如下优点:
- 无需代码检测。 所有流量都会自动跟踪可配置的跟踪级别。
- 跨微服务的一致跟踪行为。 跟踪是在 Dapr sidecar 上进行配置和管理的,因此它可以在服务之间保持一致,这些服务由不同的团队提供,并可能以不同的编程语言编写。
- 可配置和可扩展。 通过利用 Zipkin API 和 OpenTelemetry 收集器,可以将 Dapr 追踪配置为与流行的追踪后端配合使用,包括客户可能有的自定义后端。
- 可以同时定义和启用多个Exporter。
7.Secrets
应用程序通常会通过使用专用的密钥存储来秘密存储敏感信息,如连接字符串、密钥和用于与数据库、服务和外部系统进行验证的令牌。
通常这需要建立一个密钥存储,如Azure Key Vault、Hashicorp 保险库和其他仓库,并在那里存储应用程序级别的密钥。 要访问这些密钥存储,应用程序需要导入密钥存储SDK,并使用它访问这些密钥。 这可能需要相当数量的模板代码,这些代码与应用的实际业务领域无关,因此在多云场景中,可能会使用不同厂商特定的密钥存储,这就成为一个更大的挑战。
让开发人员在任何地方更容易消耗应用程序密钥, Dapr 有一个专用的密钥构建块 API ,允许开发人员从一个密钥存储获得密钥。
使用 Dapr 的密钥存储构建块通常涉及以下内容:
- 设置一个特定的密钥存储解决方案的组件。
- 在应用程序代码中使用 Dapr 密钥 API 获取密钥。
- 可选,在Dapr组件文件中引用密钥。
安装Dapr
此系列文章,我们先来依据Windows环境下的Dapr的自托管模式来实战,之后再通过K8S来运行Dapr。
1.安装 Dapr CLI 脚手架工具
Dapr CLI 是您用于各种 Dapr 相关任务的主要工具。 您可以使用它来运行一个带有Dapr sidecar的应用程序, 以及查看sidecar日志、列出运行中的服务、运行 Dapr 仪表板。
此命令提示命令将安装最新的 Windows Dapr CLI 到 C:\dapr
并将此目录添加到用户PATH 环境变量。
powershell -Command "iwr -useb https://raw.githubusercontent.com/dapr/cli/master/install/install.ps1 | iex"
验证安装
您可以通过重新启动您的终端/命令提示和运行以下操作来验证CLI:
dapr
输出显示应该如下方所示:
__ ____/ /___ _____ _____ / __ / __ '/ __ \/ ___/ / /_/ / /_/ / /_/ / / \__,_/\__,_/ .___/_/ /_/ =============================== Distributed Application Runtime Usage: dapr [command] Available Commands: completion Generates shell completion scripts components List all Dapr components. Supported platforms: Kubernetes configurations List all Dapr configurations. Supported platforms: Kubernetes dashboard Start Dapr dashboard. Supported platforms: Kubernetes and self-hosted help Help about any command init Install Dapr on supported hosting platforms. Supported platforms: Kubernetes and self-hosted invoke Invoke a method on a given Dapr application. Supported platforms: Self-hosted list List all Dapr instances. Supported platforms: Kubernetes and self-hosted logs Get Dapr sidecar logs for an application. Supported platforms: Kubernetes mtls Check if mTLS is enabled. Supported platforms: Kubernetes publish Publish a pub-sub event. Supported platforms: Self-hosted run Run Dapr and (optionally) your application side by side. Supported platforms: Self-hosted status Show the health status of Dapr services. Supported platforms: Kubernetes stop Stop Dapr instances and their associated apps. . Supported platforms: Self-hosted uninstall Uninstall Dapr runtime. Supported platforms: Kubernetes and self-hosted upgrade Upgrades a Dapr control plane installation in a cluster. Supported platforms: Kubernetes Flags: -h, --help help for dapr -v, --version version for dapr Use "dapr [command] --help" for more information about a command.
2.在本地环境中初始化 Dapr
Dapr 与您的应用程序一起作为sidecar运行,在自托管模式下,这意味着它是您本地机器上的一个进程。 因此,初始化 Dapr 包括获取 Dapr sidecar 二进制文件并将其安装到本地.
此外,默认初始化过程还创建了一个开发环境,帮助简化 Dapr 的应用开发。 这包括下列步骤:
- 运行一个用于状态存储和消息代理的Redis容器实例
- 运行一个用于提供可观察性的Zipkin容器实例
- 创建具有上述组件定义的 默认组件文件夹
- 运行用于本地演员支持的Dapr placement服务容器实例
确保以管理员方式运行命令提示符终端 (右键单击,以管理员方式运行)
安装最新的 Dapr 运行时二进制程序:
dapr init
验证
dapr --version
输出应该看起来像这样:
CLI version: 1.2.0 Runtime version: 1.4.0
验证容器正在运行
docker ps
请确保镜像为daprio/dapr
, openzipkin/zipkin
和 redis
的容器都在运行:
在 dapr init
时,CLI 还创建了一个默认组件文件夹,其中包括几个 YAML 文件,其中包含state store、elevated 和 zipkin。 Dapr sidecar, 将读取这些文件。 告诉它使用Redis容器进行状态管理和消息传递,以及Zipkin容器来收集跟踪。
- Windows 中,Dapr 初始化路径到
%USERPROFILE%\.dapr\