大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章能成为你成长路上的垫脚石,让我们一起精进。
本文是《使用Dapr和.NET 6.0进行微服务实战》的第2篇Dapr简介部分,大致包括:了解Dapr,探索Dapr核心组件,设置Dapr环境,构建Dapr简单示例,闲话不说,我们开始系列旅程吧。
Dapr全称Distributed Application Runtime,翻译过来就是分布式应用程序运行时,在v1.0发布后得到了极大的发展。
本章将向您介绍Dapr架构的核心概念,为您使用Dapr进行开发做好预热和准备工作。
可以这么说,Dapr加速了新的云原生应用的开发,并简化了微服务架构的运用。
在本章中,我们将讨论以下主题:
简单了解Dapr
探索Dapr核心组件
设置Dapr环境
构建Dapr示例
这些主题是后续使用Dapr和微服务架构的基础和理论指导。首先,我们进入开篇的第一步,从Dapr的工作原理开始。
Dapr是一个事件驱动的、可移植的运行时,由Microsoft使用开源方法创建的,由云原生计算基金会(CNCF)孵化的项目。
事件驱动(Dapr的定义中强调了这一点)在微服务中扮演着重要的角色;对来自外部系统或第三方的事件作出的反应,同时可以向其他服务转发新的事件。
Dapr是可移植的,它有三种托管模式。首先它可以在本地机器上自托管,也可以部署到边缘,或者在Kubernetes上运行。
下图显示了Dapr提供的许多构建块:
从上图可以看出,Dapr先要运行在微软Azure、亚马逊(AWS)、谷歌云或国内阿里,华为云上都是没问题的。
Dapr建立在微软开发超大规模云原生应用的经验基础上。它的灵感来自Orleans和Service Fabric(服务网格),同时又反哺微软云的大规模运用。
Dapr于2019年10月首次发布,您可以在这里上了解到。
Dapr在2020年9月,在初始开发阶段采用了开放式治理模式;请参见下面的描述.
Dapr于2021年2月发布了面向生产环境的v1.0版本,请参看这里。2021年11月,Dapr作为孵化项目加入CNCF;请参阅公告
Dapr为开发人员提供了一种面向微服务架构的设计工具和运行时,以便更好地运行我们的应用。
微服务提供了面向高可用,高并发等一系列的好处,但是同时带来了响应的复杂行,比如熔断限流,服务调用监控,负载均衡等,通常会给开发团队带来沉重的负担。
而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不是什么了。
我们从正面了解到了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命令行工具(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),微服务开发人员可以根据需求选择性地采用这些构建块,具体如下:
服务调用(Service invocation):服务调用使我们能够调用位于同一宿主环境中的其他服务,同时处理重试策略。在第4章“服务调用”中会更详细地介绍了这个构建块。
状态管理(State management):为了将应用状态作为一个简单的键值对进行有效管理。Dapr提供了许多状态存储,包括Redis、Azure Cosmos DB、Azure SQL Server和PostgreSQL,它们可以通过配置插入。在第5章的“状态管理简介”中会详细探讨。
消息的发布和订阅(pub/sub):pub/sub模式通过交换消息实现微服务之间的解耦通信,服务总线可以在生产者和消费者之间路由消息。在第6章的“发布和订阅”中会详细讨论该构建块。
资源绑定(Resource bindings):这就是Dapr的事件驱动特性所在。通过绑定,您的应用程序可以通过SMS进行触发(这只是通信API领域的流行服务之一)。第7章“资源绑定”中会更详细地介绍这个构建块。
参与者(Actors):Actors模式可以理解为单线程模型,旨在通过在大量计算单元(Actors)之间分配总请求量的负载来简化高并发场景,这些计算单元通过一次处理一个Actors的请求,在较小但独立的范围内处理任务。在第8章“使用Actors”中会详聊该构建块。
可观察性:Dapr使开发人员和运维员能够观察应用和服务的行为,而无需对它们进行检测。第11章“跟踪Dapr应用”中会更详细地介绍了这个构建块。
安全密钥(Secrets):将安全与代码分开是一种良性的做法。Dapr能够存储密钥,并从Kubernetes或Azure密钥库等其他组件中引用这些密钥。
配置(Configuration):在Alpha状态的Dapr 1.8版中引入了此构建块,它解决了检索应用程序所需配置数据的常见需求。
分布式锁(Distributed lock:):Dapr 1.8版在Alpha状态下引入分布式锁,它提供了一种强大的基于租约的机制来管理对命名锁的互斥访问。应用程序可以使用该锁来确保多个并发实例对资源的独占。
了解了Dapr体系结构和组件后,在开始使用之前,我们需要在我们的开发环境中设置Dapr。
Dapr是多个平台和语言的运行时,本专栏的重点是.NET中的C#,并使用Visual Studio Code作为开发工具。
我们使用的开发环境是Windows,如果你需要有关在Linux或macOS上执行特定操作,建议您查看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的详细说明。
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,请参阅,获取最新二进制文件的链接。
.NET 6是.NET的长期支持(LTS)版本,可获得3年免费支持和更新。
在开发机器上,建议安装包含运行时的完整版SDK。安装完成后,我们运行dotnet--info命令进行校验,成功后,您将看到以下输出:
VS Code是微软的一个很棒的跨平台源码编辑器。您可以按照以下说明免费安装它:跳转。
Dapr有一个VS Code的扩展,它有助于导航Dapr本地环境,并简化调试配置,我们强烈建议安装它。
推荐一款不错的新的Windows终端Windows Terminal,是一款新式、快速、高效、强大且高效的终端应用程序,适用于命令行工具和命令提示符,PowerShell和 WSL 等 Shell 用户。在接下来的章节中,我们通常必须并行运行多个命令和工具。因此,Windows终端的选项卡功能也是我建议您采用它的原因之一。
Dapr可以以两种模式初始化:自托管和Kubernetes。
由于打算用于开发环境,所以这里采用自托管模式,执行Dapr init
后,会在本地会默认安装Redis、Dapr placement services和Zipkin。
这里要留意的是Dapr init命令,建议在网络比较好的早晨进行初始化,如果是下午或者晚上,可能会无法成功。
默认情况下,Dapr二进制文件和默认组件位于%USERPROFILE%.dpr\文件夹中。
例如,在本地开发环境中,Dapr打算用于Redis的端口可能已经被占用。在这种情况下,您应该确定哪些进程或容器正在使用该端口,并相应地更改它们。
一旦启动init命令成功,您会看到如下输出:
PS C:\Repos\practical-dapr\chapter01> dapr init
Making the jump to hyperspace...
Installing runtime version 1.8.4
Downloading 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_placement
openzipkin/zipkin - 9410/tcp, 0.0.0.0:9411->9411/tcp, :::9411-
>9411/tcp - dapr_zipkin
redis - 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp - dapr_redis
下面是在Linux下的验证:
Dapr专门用于在Kubernetes上执行。在安装了Dapr CLI的开发机器上,可以在Kubernetes集群上设置Dapr:dapr init -k
或者,您可以使用Helm v3 chart在Kubernetes上安装Dapr。您可以在官网上查看详情。
要验证k8s当中的安装是否成功完成,请执行以下命令kubectl get pods --namespace dapr-system
Linux下的效果是这样的:
在开发环境是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 --version
CLI version: 1.9.1
Runtime version: 1.9.5
我们的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 _logger;
public HelloController(ILogger logger)
{
_logger = logger;
}
[HttpGet()]
public ActionResult Get()
{
Console.WriteLine("Hello, World.");
return "Hello, World";
}
}
以上我们设置了路由和一个Get方法。
(6)为了运行Dapr应用程序,可以使用以下命令:dapr run --app-id
我们将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 run
You're up and running! Both Dapr and your app logs will
appear here.
在此阶段,ASP.NET在端口5000上进行监听,Dapr在端口5010上进行监听。为了测试Dapr,我们按如下方式调用curl命令,使用浏览器也可以:
PS C:\Repos\practical-dapr> curl http://localhost:5010/v1.0/invoke/hello-world/method/hello
Hello, 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仪表板仅显示我们在开发机器上运行的示例应用程序。在Kubernetes环境中,它将显示所有正在运行的微服务以及其他组件:
Dapr仪表板显示,部署了Zipkin,Redis,Redis除了做状态存储,还支持消息的发布订阅。
以上就是我们构建的第一个Dapr示例。
在本章,您了解了Dapr项目及其组件、构建块和sidecar方法。所有这些概念将在后面的章节中单独深入探讨。同时,我们还演示了在本地开发机器上设置Dapr,准备必要的工具。我们还学习了如何创建一个简单的ASP.NET项目,以及如何配置和检查Dapr,我们还了解了Dapr仪表板,我们可以从中获得Dapr环境的完整和即时视图。
在下一章中,我们将使用环境来学习如何调试Dapr。
Dapr提供哪些构建块?
Dapr CLI和Dapr运行时之间的关系是什么?
如何在本地开发环境中安装Dapr?
在Kubernetes中,可以采用哪些方法安装Dapr?
Dapr 知多少 | 分布式应用运行时圣杰兄的这篇文章,图文并茂地讲述了Dapr核心组件的功能,推荐阅读。
Dapr概述:https://docs.dapr.io/concepts/overview/
Dapr入门:https://docs.dapr.io/getting-started/
Dapr路线图:https://docs.dapr.io/contributing/roadmap/