使用Dapr和.NET 6.0进行微服务实战:Dapr简介

前言

了解Dapr,探索Dapr核心组件,设置Dapr环境,构建Dapr简单示例,闲话不说,我们开始系列旅程吧。

导读

Dapr全称Distributed Application Runtime,翻译过来就是分布式应用程序运行时,在v1.0发布后得到了极大的发展。本章将向你介绍Dapr架构的核心概念,为您使用Dapr进行开发做好预热和准备工作。

可以这么说,Dapr加速了新的云原生应用的开发,并简化了微服务架构的运用。在本章中,我们将讨论以下主题:.

  • 简单了解Dapr

  • 探索Dapr核心组件

  • 设置Dapr环境

  • 构建Dapr示例

这些主题是后续使用Dapr和微服务架构的基础和理论指导。首先,我们进入开篇的第一步,从Dapr的工作原理开始。

一、简单了解Dapr

Dapr是一个事件驱动的、可移植的运行时,由Microsoft使用开源方法创建的,由云原生计算基金会(CNCF)孵化的项目。

事件驱动(Dapr的定义中强调了这一点)在微服务中扮演着重要的角色;对来自外部系统或第三方的事件作出的反应,同时可以向其他服务转发新的事件。

Dapr是可移植的,它有三种托管模式。首先它可以在本地机器上自托管,也可以部署到边缘,或者在Kubernetes上运行。下图显示了Dapr提供的许多构建块:
使用Dapr和.NET 6.0进行微服务实战:Dapr简介
从上图可以看出,Dapr先要运行在微软Azure、亚马逊(AWS)、谷歌云或国内阿里,华为云上都是没问题的。

Dapr建立在微软开发超大规模云原生应用的经验基础上。它的灵感来自Orleans和Service Fabric(服务网格),同时又反哺微软云的大规模运用。

1.1、Dapr简史

Dapr于2019年10月首次发布,您可以在这里上了解到。Dapr在2020年9月,在初始开发阶段采用了开放式治理模式;请参见下面的描述.Dapr于2021年2月发布了面向生产环境的v1.0版本,请参看这里。

2021年11月,Dapr作为孵化项目加入CNCF;请参阅公告Dapr为开发人员提供了一种面向微服务架构的设计工具和运行时,以便更好地运行我们的应用。微服务提供了面向高可用,高并发等一系列的好处,但是同时带来了响应的复杂行,比如熔断限流,服务调用监控,负载均衡等,通常会给开发团队带来沉重的负担。

而Dapr运行时刚好可以帮助我们简化以上复杂性操作,我们看看具体如何操作:

使用Dapr和.NET 6.0进行微服务实战:Dapr简介
(图1.2)

如图1.2所示,它显示了两种Dapr托管模式:Dapr运行时在边车(sidecar)进程中运行,将应用的大部分复杂性提升到一个单独的环境中,这大大简化了开发和操作。这些sidecar进程在您的开发环境的本地运行,或者在Kubernetes的Pod的容器中运行。

从应用程序的角度来看,Dapr是一种应用编程接口(API),可以通过超文本传输协议(HTTP)、远程过程调用(gRPC)直接访问,或者更简单地说,可以通过适用于.NET、Java、Go、Python、PHP、JavaScript、C++和Rust语言的任何软件开发工具包(SDK)直接访问。

当然,你也可以不必采用Dapr SDK(稍后将体验到),对Dapr服务的请求可以像对HTTP调用一样简单,例如:http://localhost:3500/v1.0/invoke//method/。如果您通过Dapr SDK与Dapr交互,或者使用Actor SDK利用Dapr Actor模型,那么使用SDK确实会带来许多好处。您可以在Dapr文档中了解有关SDK和支持的语言的更多信息,网址。

我们已经了解了Dapr的架构,知道Dapr是什么了,接下来我们要澄清下Dapr不是什么了。

1.2、Dapr不是什么

我们从正面了解到了Dapr,也许你对此颇感兴趣,但是我觉得很有必要全面了解Dapr,我们需要介绍一下Dapr不是什么。这使有利我们消除对Dapr产生的误解,如下所示:

  • Dapr不会强迫开发人员接受具有严格规则和约束的编程模型。相反,虽然Dapr把开发人员从微服务架构的复杂性中解放出来,但开发人员并没有被规定要如何编写应用程序。例如,对存储状态的数据库的连接的管理是Dapr的责任(后续的状态管理会看到),当它对微服务应用是透明的。

  • Dapr不是服务网格。虽然Dapr和服务网格可以找到许多相似之处,但Dapr是在应用级别提供能力,而服务网格在基础架构上运行。如果出现冲突或间歇性问题,开发人员有权决定如何处理Dapr可能返回的错误;无论是采用Dapr的重试策略,还是向客户端返回错误,或者补偿操作,这些都是只有开发人员才有权限做出决定。

Dapr旨在与Istio等服务网格集成,这超出了本专栏的范围。

  • Dapr不是Microsoft云服务。它确实帮助开发人员在云中构建微服务应用程序,它当然提供了许多与Azure云服务的集成,但它也为AWS、GCP和其他服务提供了同样多的组件。同时,Azure在具有本机扩展的Azure Kubernetes Service(AKS)、具有Dapr策略的Azure API管理以及具有Dapr本机集成的Azure容器应用程序中确实为Dapr提供了丰富的支持。

  • Dapr不是一种仅限.NET的技术。Dapr本身是用Go语言编写的,任何语言都可以利用它。我们可以使用多种语言的SDK,但也可以选择直接与Dapr API交互,而无需任何额外的SDK库。

注意事项
虽然本专栏偏向.NET,但作为示例,我也会演示Dapr和Python的使用关系。

希望以上介绍能让你对Dapr的了解会更加全面、客观,并为你是否采用这项技术提供选项帮助。接下来,我们将专门介绍Dapr的体系结构。

二、探索Dapr核心组件

Dapr从一开始就被设计为一组可插拔的构建块,开发人员可以依赖该构建块或叫基础设施进行开发,而运维人员可以通过简单地配置就可以让使应用适配其托管环境。

以下是Dapr工具和组件的完整列表:

  • Dapr命令行工具(CLI):用于配置、管理和监视Dapr环境的跨平台命令行工具。它也是用于本地调试Dapr应用的工具。

  • Dapr Helm Charts:提供了在Kubernetes环境中安装和更新Dapr的手段。

  • Dapr API:定义应用如何与Dapr运行时交互,使用其构建块的API。

  • Dapr runtime:这是实现Dapr API的核心。如果您很好奇,可以在Dapr的存储库中查看它是如何开发的.

  • Dapr host:在开发机器上,主机作为独立进程运行;在Kubernetes中,它是应用pod中的一个sidecar容器。

  • Dapr operator:针对Kubernetes模式,该operator用于管理绑定和配置。

  • Dapr sidecar injector(边车注入):一旦在Kubernetes下配置了该服务,它会将Dapr sidecar注入到应用程序的pod中。

  • Dapr placement service:该服务的目的是在Dapr pod中分发(或放置)Actor实例。

  • Dapr Sentry(哨兵):一个内置的证书颁发机构(CA),用于颁发和管理Dapr使用的证书,以提供透明的互传输层安全(mTLS)。

截至目前v1.9版本,Dapr提供了九大构建块(building blocks),微服务开发人员可以根据需求选择性地采用这些构建块,具体如下:

1、服务调用(Service invocation):服务调用使我们能够调用位于同一宿主环境中的其他服务,同时处理重试策略。在第4章“服务调用”中会更详细地介绍了这个构建块。

2、状态管理(State management):为了将应用状态作为一个简单的键值对进行有效管理。Dapr提供了许多状态存储,包括Redis、Azure Cosmos DB、Azure SQL Server和PostgreSQL,它们可以通过配置插入。在第5章的“状态管理简介”中会详细探讨。

3、消息的发布和订阅(pub/sub):pub/sub模式通过交换消息实现微服务之间的解耦通信,服务总线可以在生产者和消费者之间路由消息。在第6章的“发布和订阅”中会详细讨论该构建块。

4、资源绑定(Resource bindings):这就是Dapr的事件驱动特性所在。通过绑定,您的应用程序可以通过SMS进行触发(这只是通信API领域的流行服务之一)。第7章“资源绑定”中会更详细地介绍这个构建块。

5、参与者(Actors):Actors模式可以理解为单线程模型,旨在通过在大量计算单元(Actors)之间分配总请求量的负载来简化高并发场景,这些计算单元通过一次处理一个Actors的请求,在较小但独立的范围内处理任务。在第8章“使用Actors”中会详聊该构建块。

6、可观察性:Dapr使开发人员和运维员能够观察应用和服务的行为,而无需对它们进行检测。第11章“跟踪Dapr应用”中会更详细地介绍了这个构建块。

7、安全密钥(Secrets):将安全与代码分开是一种良性的做法。Dapr能够存储密钥,并从Kubernetes或Azure密钥库等其他组件中引用这些密钥。

8、配置(Configuration):在Alpha状态的Dapr 1.8版中引入了此构建块,它解决了检索应用程序所需配置数据的常见需求。

9、分布式锁(Distributed lock:):Dapr 1.8版在Alpha状态下引入分布式锁,它提供了一种强大的基于租约的机制来管理对命名锁的互斥访问。应用程序可以使用该锁来确保多个并发实例对资源的独占。
了解了Dapr体系结构和组件后,在开始使用之前,我们需要在我们的开发环境中设置Dapr。

3、设置Dapr环境

Dapr是多个平台和语言的运行时,本专栏的重点是.NET中的C#,并使用Visual Studio Code作为开发工具。

我们使用的开发环境是Windows,如果你需要有关在Linux或macOS上执行特定操作,建议您查看Dapr官方文档。

Dapr路线图

Dapr运行时于2021年2月发布v1.0生产环境版本,我们可以在Dapr官方博客中查看到,Dapr于2021年发布了五个新的次要版本。您可以在Dapr路线图中查看。本专栏中的示例和脚本已经用Dapr的v1.9进行了更新和测试。

接下来,我们将完成以下步骤:

  • 配置Docker

  • 安装Dapr CLI

  • 安装.NET 6.0

  • 安装VS Code

  • 安装Windows终端

  • 在自托管模式下安装Dapr

  • 在Kubernetes上安装Dapr

配置Docker

Docker的安装很简单,我们可以在以下位置找到运行Docker的详细说明。

安装Dapr CLI

Dapr运行时安装也不难,您可以在此访问安装。在Windows上,执行以下命令将CLI安装到c:\dapr目录中,并将其添加到用户PATH环境变量中,以便可以从命令行轻松使用工具:
powershell -Command "iwr -useb https://raw.githubusercontent.com/dapr/cli/master/install/install.ps1 | iex"
有关Dapr CLI的更多详细信息,请参阅。

安装.NET 6.0

要安装.NET 6,请参阅,获取最新二进制文件的链接。
.NET 6是.NET的长期支持(LTS)版本,可获得3年免费支持和更新。
在开发机器上,建议安装包含运行时的完整版SDK。安装完成后,我们运行dotnet--info命令进行校验,成功后,你将看到以下输出:

安装VS Code

VS Code是微软的一个很棒的跨平台源码编辑器。您可以按照以下说明免费安装它:跳转。

Dapr扩展

Dapr有一个VS Code的扩展,它有助于导航Dapr本地环境,并简化调试配置,我们强烈建议安装它。

安装Windows终端

推荐一款不错的新的Windows终端Windows Terminal,是一款新式、快速、高效、强大且高效的终端应用程序,适用于命令行工具和命令提示符,PowerShell和 WSL 等 Shell 用户。

在接下来的章节中,我们通常必须并行运行多个命令和工具。因此,Windows终端的选项卡功能也是我建议您采用它的原因之一。

在自托管模式下安装Dapr

Dapr可以以两种模式初始化:自托管和Kubernetes。由于打算用于开发环境,所以这里采用自托管模式,执行Dapr init后,会在本地会默认安装Redis、Dapr placement services和Zipkin。

这里要留意的是Dapr init命令,建议在网络比较好的早晨进行初始化,如果是下午或者晚上,可能会无法成功。

默认情况下,Dapr二进制文件和默认组件位于%USERPROFILE%.dpr\文件夹中。例如,在本地开发环境中,Dapr打算用于Redis的端口可能已经被占用。在这种情况下,您应该确定哪些进程或容器正在使用该端口,并相应地更改它们。一旦启动init命令成功,您会看到如下输出:

PS C:\Repos\practical-dapr\chapter01> dapr initMaking the jump to hyperspace...Installing runtime version 1.8.4Downloading binaries and setting up components...Downloaded binaries and completed components set up.daprd binary has been installed to C:\Users\dabedin\.dapr\bin.dapr_placement container is running.dapr_redis container is running.dapr_zipkin container is running.Use `docker ps` to check running containers.Success! Dapr is up and running. To get started, go here: https://aka.ms/dapr-getting-started

我们可以通过docker ps来验证一下是否成功:

PS C:\Repos\practical-dapr\chapter01> docker ps --format "{{.Image}} - {{.Ports}} - {{.Names}}"daprio/dapr:1.8.4 - 0.0.0.0:6050->50005/tcp, :::6050->50005/tcp- dapr_placementopenzipkin/zipkin - 9410/tcp, 0.0.0.0:9411->9411/tcp, :::9411->9411/tcp - dapr_zipkinredis - 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp - dapr_redis

下面是在Linux下的验证:

使用Dapr和.NET 6.0进行微服务实战:Dapr简介

在Kubernetes上安装Dapr

Dapr专门用于在Kubernetes上执行。在安装了Dapr CLI的开发机器上,可以在Kubernetes集群上设置Dapr:
dapr init -k
或者,您可以使用Helm v3 chart在Kubernetes上安装Dapr。您可以在官网上查看详情。要验证k8s当中的安装是否成功完成,请执行以下命令
kubectl get pods --namespace dapr-system
Linux下的效果是这样的:

使用Dapr和.NET 6.0进行微服务实战:Dapr简介

更新Dapr版本

在开发环境是Windows的机器上,Dapr的早期版本已经存在,只需使用我们在上面提到的命令重新安装即可更新CLI。
如官网文档所述,我们必须先卸载Dapr,如下所示:
PS C:\Repos\practical-dapr\chapter01> dapr uninstall --all
更新CLI并卸载Dapr后,我们可以按如下方式重新安装Dapr:
PS C:\Repos\practical-dapr\chapter01> dapr init

切记在早上网络好一点的时候进行初始化,具体原因你懂的。

在执行dapr-init之后,检查dapr版本,我们可以看到CLI和运行时的版本都从1.0向前移动到1.9.5,如以下代码片段所示:

PS C:\Repos\practical-dapr\chapter01> dapr --versionCLI version:  1.9.1 Runtime version: 1.9.5

我们的Dapr测试环境已启动并正在运行。我们现在准备用我们的第一个示例进行试验。

4、构建Dapr示例

我们将构建一个返回hello world消息的web API。我们选择将所有样本都放在C:\Repos\pactual dapr\文件夹中,并为第一个样本创建了C:\Repos\Pactual dapr_chapter01文件夹。我们的步骤如下:
(1)创建Web API ASP.NET项目

PS C:\Repos\practical-dapr\chapter01> dotnet new webapi -o dapr.microservice.webapi

(2)添加Dapr SDK引用

PS C:\Repos\practical-dapr\chapter01> dotnet add package Dapr.AspNetCore --version 1.9.5

(3)我们用Vs Code打开项目,并对生成的模板做些更改

(4)为了在ASP.NET 6中支持Dapr,我们对Program.cs中的代码进行了一些更改。我们将builder.Services.AddControllers方法更改为builder.Services.addController().AddDapr()。
最后,为了简化代码,我们注释掉app.UseHttpsRedirection()中间件。
最后看下最终的代码:

var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers().AddDapr();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
//app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.MapSubscribeHandler();
app.Run();

(5)最后,我们添加了一个名为HelloWorldController的控制器,如以下代码片段所示:

[ApiController]
[Route("[controller]")]
public class HelloController : ControllerBase
{
    private readonly ILogger<HelloController> _logger;

    public HelloController(ILogger<HelloController> logger)
    {
        _logger = logger;
    }

    [HttpGet()]
    public ActionResult<string> Get()
    {
        Console.WriteLine("Hello, World.");
        return "Hello, World";
    }
}

以上我们设置了路由和一个Get方法。
(6)为了运行Dapr应用程序,可以使用以下命令:
dapr run --app-id <my app id> --app-port <port of the app> --dapr-http-port <port in Dapr> dotnet run
我们将ASP.NET默认端口设为5000,将Dapr HTTP端口设为5010。以下命令行启动Dapr应用程序:

PS C:\Repos\dapr.microservice.webapi> dapr run --app-id hello-world --app-port 5000 --dapr-http-port 5010 dotnet run

我们在对应的项目目录下执行以上代码,启动Dapr。Dapr将为HTTP使用端口5010,而对于gRPC,它将自动选择一个可用端口。
启动后会在控制台打印日志信息,要确认应用程序在Dapr运行时上下文中正确运行:

Updating metadata for app command: dotnet runYou're up and running! Both Dapr and your app logs willappear here.

在此阶段,ASP.NET在端口5000上进行监听,Dapr在端口5010上进行监听。为了测试Dapr,我们按如下方式调用curl命令,使用浏览器也可以:

PS C:\Repos\practical-dapr> curl http://localhost:5010/v1.0/invoke/hello-world/method/helloHello, World

Dapr返回了这个响应,同时Dapr窗口也会打印结果,如下所示

== APP == Hello, World.

(7)从另一个窗口,让我们验证Dapr服务的详细信息。我们按如下方式打开dapr仪表板,而不是使用dapr list命令
PS C:\Windows\System32> dapr dashboard Dapr Dashboard running on http://localhost:8080
我们可以通过导航到http://localhost:8080显示了hell-world的详细信息:

使用Dapr和.NET 6.0进行微服务实战:Dapr简介
在本例中,Dapr仪表板仅显示我们在开发机器上运行的示例应用程序。在Kubernetes环境中,它将显示所有正在运行的微服务以及其他组件:

使用Dapr和.NET 6.0进行微服务实战:Dapr简介

Dapr仪表板显示,部署了Zipkin,Redis,Redis除了做状态存储,还支持消息的发布订阅。
以上就是我们构建的第一个Dapr示例。

5、总结

在本章你了解了Dapr项目及其组件、构建块和sidecar方法。所有这些概念将在后面的章节中单独深入探讨。

同时,我们还演示了在本地开发机器上设置Dapr,准备必要的工具。我们还学习了如何创建一个简单的ASP.NET项目,以及如何配置和检查Dapr,我们还了解了Dapr仪表板,我们可以从中获得Dapr环境的完整和即时视图。
在下一章中,我们将使用环境来学习如何调试Dapr。

6、问题

1、Dapr提供哪些构建块?

2、Dapr CLI和Dapr运行时之间的关系是什么?

3、如何在本地开发环境中安装Dapr?

4、在Kubernetes中,可以采用哪些方法安装Dapr?