使用 Dapr .NET SDK 开发应用程序
Dapr .NET SDK 的部署集成
同时考虑多个服务
使用你喜欢的 IDE 或编辑器启动应用程序时,通常假设你只需要运行一个东西:你正在调试的应用程序。然而,开发微服务会挑战你思考本地开发流程时同时考虑多个服务。微服务应用程序包含多个你可能需要同时运行的服务,以及需要管理的依赖项(如状态存储)。
在开发流程中加入 Dapr 意味着你需要管理以下关注点:
- 你想要运行的每个服务
- 每个服务的 Dapr 边车
- Dapr 组件和配置清单
- 额外的依赖项,如状态存储
- 可选:用于 Actor 的 Dapr Placement 服务
本文档假设你正在构建一个生产应用程序,并希望创建可重复且稳健的开发实践。此处提供的指导是通用的,适用于使用 Dapr 的任何 .NET 服务器应用程序(包括 Actor)。
管理组件
对于使用 Dapr 进行本地开发,你有两种主要方法来存储组件定义:
- 使用默认位置(
~/.dapr/components) - 使用你自己的位置
在源代码仓库中创建一个文件夹来存储组件和配置,将使你能够对这些定义进行版本控制和共享。此处提供的指导假设你在应用程序源代码旁边创建了一个文件夹来存储这些文件。
开发选项
选择以下链接之一,了解你可以在本地开发场景中使用的工具。建议你熟悉其中的每一个,以了解 .NET SDK 提供的选项。
1 - 使用 Dapr CLI 进行 Dapr .NET SDK 开发
了解如何使用 Dapr CLI 进行本地开发
Dapr CLI
可以将本文视为 Docker 自托管 Dapr 指南 的 .NET 伴侣指南。
Dapr CLI 为您提供了一个良好的开发基础,它会初始化本地 Redis 容器、Zipkin 容器、placement 服务以及 Redis 的组件清单。这使您可以在全新安装且无需额外设置的情况下,使用以下构建块:
您可以使用 dapr run 来运行 .NET 服务,作为本地开发的策略。计划为每个服务运行以下命令之一以启动您的应用程序。
- 优点: 由于这是默认 Dapr 安装的一部分,因此设置起来很容易
- 缺点: 这会在您的机器上使用长时间运行的 Docker 容器,这可能并不理想
- 缺点: 这种方法的可扩展性较差,因为它需要为每个服务单独运行命令
使用 Dapr CLI
对于每个服务,您需要选择:
- 用于寻址的唯一 app-id(
app-id) - 用于 HTTP 的唯一监听端口(
port)
您还应该决定在哪里存储组件(components-path)。
以下命令可以在多个终端中运行以启动每个服务,并将相应的值替换进去。
dapr run --app-id <app-id> --app-port <port> --components-path <components-path> -- dotnet run -p <project> --urls http://localhost:<port>
说明: 此命令将使用 dapr run 来启动每个服务及其边车。命令的前半部分(在 -- 之前)将所需的配置传递给 Dapr CLI。命令的后半部分(在 -- 之后)将所需的配置传递给 dotnet run 命令。
💡 端口
由于您需要为每个服务配置唯一的端口,您可以使用此命令将该端口值传递给 Dapr 和服务两者。--urls http://localhost:<port> 将配置 ASP.NET Core 在提供的端口上监听流量。在命令行中使用配置比在其他地方硬编码监听端口更灵活。如果您的任何服务不接受 HTTP 流量,则通过删除 --app-port 和 --urls 参数来修改上述命令。
后续步骤
如果您需要调试,请使用调试器的附加功能附加到正在运行的进程之一。
如果您想扩展这种方法,请考虑构建一个脚本,为整个应用程序自动执行此过程。
2 - 使用 Docker Compose 进行 Dapr .NET SDK 开发
了解如何使用 Docker Compose 进行本地开发
Docker Compose
可将本文视为 使用 Docker 自托管 Dapr 指南 的 .NET 伴侣指南。
docker-compose 是随 Docker Desktop 附带的 CLI 工具,可用于同时运行多个容器。它是一种将多个容器的生命周期进行自动化的方式,并为面向 Kubernetes 的应用提供类似生产环境的开发体验。
- 优点: 由于
docker-compose 会为你管理容器,你可以将依赖项作为应用定义的一部分,并停止机器上长期运行的容器。 - 缺点: 投入成本最高,服务需要容器化才能开始使用。
- 缺点: 如果你不熟悉 Docker,可能会难以调试和排查故障。
使用 docker-compose
从 .NET 的角度来看,对于 Dapr 的 docker-compose 不需要专门的指导。docker-compose 运行容器,一旦你的服务进入容器中,其配置与任何其他编程技术类似。
💡 应用端口
在容器中,ASP.NET Core 应用默认监听端口 80。稍后配置 --app-port 时请记住这一点。总结方法如下:
- 为每个服务创建一个
Dockerfile - 创建一个
docker-compose.yaml 并将其签入源代码仓库
要了解如何编写 docker-compose.yaml,你应该从 Hello, docker-compose 示例 开始。
与使用 dapr run 在本地运行的每个服务类似,你需要选择一个唯一的 app-id。选择容器名称作为 app-id 会更容易记忆。
compose 文件至少包含:
- 容器用于通信的网络
- 每个服务的容器
- 指定了服务端口和 app-id 的
<service>-daprd 边车容器 - 在容器中运行的其他依赖项(例如 redis)
- 可选:Dapr placement 容器(用于 Actor)
你还可以从 eShopOnContainers 示例应用中查看更大的示例。
3 - 使用 .NET Aspire 进行 Dapr .NET SDK 开发
了解使用 .NET Aspire 进行本地开发
.NET Aspire
.NET Aspire 是一种开发工具,
旨在通过提供一个框架,使第三方服务能够与您自己的软件一起轻松集成、观察和配置,从而更轻松地将外部软件包含到 .NET 应用程序中。
Aspire 通过与流行的 IDE 提供丰富的集成来简化本地开发,包括
Microsoft Visual Studio、
Visual Studio Code、
JetBrains Rider 等,
以便在启动调试器启动应用程序的同时,自动启动和配置对其他集成的访问,包括 Dapr。
虽然 Aspire 还协助将应用程序部署到各种云主机(如 Microsoft Azure 和 Amazon AWS),但部署目前超出了本指南的范围。更多信息可以在 Aspire 的文档这里找到。
可以在这里找到一个端到端演示,其中包含以下内容并演示了多个启用 Dapr 的服务之间的服务调用。
前提条件
通过 CLI 使用 .NET Aspire
我们将首先创建一个全新的 .NET 应用程序。打开您喜欢的 CLI 并导航到您希望在其中创建新 .NET 解决方案的目录。首先使用以下命令安装一个模板,该模板将创建一个空的 Aspire 应用程序:
dotnet new install Aspire.ProjectTemplates
安装完成后,继续在当前目录中创建一个空的 .NET Aspire 应用程序。-n 参数允许您指定输出解决方案的名称。如果排除该参数,.NET CLI 将改为使用输出目录的名称,例如 C:\source\aspiredemo 将导致解决方案被命名为 aspiredemo。本教程的其余部分将假设解决方案名为 aspiredemo。
dotnet new aspire -n aspiredemo
这将在您的目录中创建两个 Aspire 特定的目录和一个文件:
aspiredemo.AppHost/ 包含 Aspire 编排项目,用于配置应用程序中使用的每个集成。aspiredemo.ServiceDefaults/ 包含一系列旨在您的解决方案中共享的扩展,以帮助 Aspire 提供的弹性、服务发现和遥测功能(这些与 Dapr 本身提供的功能不同)。aspiredemo.sln 是维护当前解决方案布局的文件
接下来,我们将创建两个项目,作为我们的 Dapr 应用程序并演示 Dapr 功能。在同一目录中,使用以下命令创建一个名为 FrontEndApp 的空 ASP.NET Core 项目和另一个名为 ‘BackEndApp’ 的项目。任何一个都将在当前目录下的 FrontEndApp\FrontEndApp.csproj 和 BackEndApp\BackEndApp.csproj 中创建。
dotnet new web --name FrontEndApp
接下来,我们将配置 AppHost 项目以添加必要的包以支持本地 Dapr 开发。使用以下命令导航到 AppHost 目录,并将 CommunityToolkit.Aspire.Hosting.Dapr 包从 NuGet 安装到项目中。
我们还将添加对 FrontEndApp 项目的引用,以便我们可以在注册过程中引用它。
此包以前称为
Aspire.Hosting.Dapr,已被
标记为已弃用。
cd aspiredemo.AppHost
dotnet add package CommunityToolkit.Aspire.Hosting.Dapr
dotnet add reference ../FrontEndApp/
dotnet add reference ../BackEndApp/
接下来,我们需要将 Dapr 配置为与您的项目一起加载的资源。在您喜欢的 IDE 中打开该项目中的 Program.cs 文件。它应该类似于以下内容:
var builder = DistributedApplication.CreateBuilder(args);
builder.Build().Run();
如果您熟悉 ASP.NET Core 项目或其他使用 Microsoft.Extensions.DependencyInjection 功能的项目中使用的依赖注入方法,您会发现这是一个熟悉的体验。
由于我们已经添加了对 MyApp 的项目引用,因此我们需要在此配置中首先添加一个引用。在 builder.Build().Run() 行之前添加以下内容:
var backEndApp = builder
.AddProject<Projects.BackEndApp>("be")
.WithDaprSidecar();
var frontEndApp = builder
.AddProject<Projects.FrontEndApp>("fe")
.WithDaprSidecar();
由于项目引用已添加到此解决方案,您的项目在此处作为 Projects. 命名空间中的类型显示。在此教程中,为项目分配的变量名称并不重要,但如果您想使用 Aspire 的服务发现功能在此项目与另一个项目之间创建引用,则将使用该名称。
添加 .WithDaprSidecar() 将 Dapr 配置为 .NET Aspire 资源,以便当项目运行时,边车将与您的应用程序一起部署。这接受许多不同的选项,并且可以按照以下示例进行配置:
DaprSidecarOptions sidecarOptions = new()
{
AppId = "how-dapr-identifies-your-app",
AppPort = 8080, //请注意,如果您打算从 Aspire v9.0 开始配置发布订阅、actor 或工作流,则需要此参数
DaprGrpcPort = 50001,
DaprHttpPort = 3500,
MetricsPort = 9090
};
builder
.AddProject<Projects.BackEndApp>("be")
.WithReference(myApp)
.WithDaprSidecar(sidecarOptions);
如上例所示,从 .NET Aspire 9.0 开始,如果您打算使用 Dapr 需要调用您的应用程序的任何功能,例如发布订阅、actor 或工作流,您需要将 AppPort 指定为配置选项,因为 Aspire 不会在运行时自动将其传递给 Dapr。预计这种行为将在未来版本中发生变化,因为修复已合并,可以在
这里进行跟踪。
最后,让我们向后端应用添加一个端点,我们可以使用 Dapr 的服务调用调用它以显示到页面以演示 Dapr 正在按预期工作。
当您在 IDE 中打开解决方案时,请确保 aspiredemo.AppHost 配置为您的启动项目,但是当您以调试配置启动它时,您会注意到您的集成控制台应该反映您预期的 Dapr 日志,并且它将对您的应用程序可用。