.Net 7 轻松上手Dapr之服务调用
前言
对于Dapr ,在项目中也有用过一段时间,优缺点并存,但是瑕不掩瑜,目前随着版本的迭代和第三方团队对它的支持也使得我们用得更加得心应手,所以借此也回顾一下Dapr的相关知识以及分享一下项目中用到的第三方库MASA.Framework 对Dapr的完美支持。然后本文只是个人学习与分享,不喜勿喷,谢谢!
什么是Dapr?
Dapr 是 Distributed Application Runtime (分布式应用运行时)的缩写。
Dapr是一种可移植的,serverless的,事件驱动的运行时,它使开发人员可以轻松构建弹性,无状态和有状态微服务,这些服务运行在云和边缘上,并包含多种语言和开发框架。
Dapr 的概念模型图:
官方介绍
Dapr 环境配置
网上对于dapr自托管模式下的环境配置的教程也比较多了,所以这里就只简单介绍介绍几个需要注意的地方。首先在安装Dapr之前你或许需要能够进行科学的上网,如果发现冲浪速度不理想的话,那就或许需要在夜深人静的时候偷波塔了,当然你也可以选择离线安装,也比较简单,相信聪明的你们都能够一一搞定。
安装 Dapr CLI
执行命令:
powershell -Command "iwr -useb https://raw.githubusercontent.com/dapr/cli/master/install/install.ps1 | iex"
此命令会安装最新的 windows Dapr cli 并将$Env:SystemDrive\dapr此目录添加到用户 PATH 环境变量
然后通过重新启动终端/命令提示符并运行 dapr 命令来验证 CLI 是否已安装:
dapr
也可以在C盘和系统环境变量中查看验证
详细步骤可以参考 安装 Dapr CLI
安装 Docker Desktop
然后因为Dapr CLI默认会在Docker内启动 redis、zipkin、placement。所以我们可以安装个Docker Desktop来增加dapr的体验性。安装完成后默认开启WSL2。
详细步骤可以参考 安装 Docker Desktop
当然还可以参考大佬的文章手把手教你学Dapr - 3. 使用Dapr运行第一个.Net程序
初始化 Dapr
初始化dapr后,我们可以
- 在本地获取并安装 Dapr sidecar 二进制文件。
- 使用 Dapr 创建一个简化应用程序开发的开发环境。
Dapr初始化包括:
- 运行Redis 容器实例以用作本地状态存储和消息代理。
- 运行Zipkin 容器实例以实现可观察性。
- 使用上述组件定义创建默认组件文件夹。
- 运行Dapr 放置服务容器实例以支持本地参与者。
首先我们如果只使用dapr的服务调用的话,就可以只安装精简版。
dapr init --slim
如果想体验dapr完整功能支持的话,可以执行
dapr init
这里会从外网上拉取一些二进制文件,如果网络不好的话可能需要等待一段时间,如果长时间未能完成或出现网络相关错误的话,可以多尝试几次或者选择离线安装。
离线安装这里稍微介绍:
执行上述dapr初始化命令后,无论最后是否成功,都会在C:\Users\Administrator.dapr生成一些文件 如:
然后如果最后失败的话,可能会导致bin文件中拉取的内容不完整。正常情况是这样:
所以我们离线安装的话,可以先使用命令
Dapr uninstall //删除bin文件夹 (这里选择此命令)
Dapr uninstall --all //删除 C:\Users\Administrator\.dapr
就可以自己去dapr 的GitHub上下载对应版本的文件压缩包,然后把文件放入bin文件夹中即可。一般情况下,会自动解压缩。
- dashboard_windows_amd64.zip
- daprd_windows_amd64.zip
安装完成后可以执行命令验证:
dapr -v
详细步骤可以参考初始化 Dapr
项目准备
- dotNet 7
- Docker Desktop
- Visual Studio 2022
- Dapr
项目搭建
我们先准备一个客户端项目-DaprClientWeb与两个服务端项目-ServiceA与ServiceB
然后先在两个服务端项目中分别增加一个测试接口
ServiceA 项目示例
接下来我们先用dapr cli 请求接口验证一下环境可行性
使用命令行工具,跳转到ServiceA的源码目录,执行命令:
dapr run --app-id service-a --app-port 5001 dotnet run
这个命令会调用基础 Dapr 运行时,并使应用程序和 Dapr sidecar一起运行
然后输入以下命令查看 Dapr sidecar是否启动成功:
dapr list
最后接着输入以下命令访问接口:
dapr invoke --app-id service-a --method GetServiceA --verb GET
OK,环境到此验证完毕,项目也基本上搭建完成,下面会借助客户端项目-DaprClientWeb 通过Dapr .Net SDK来分别请求ServiceA与ServiceB的接口 演示Dapr的服务调用。
Dapr 服务调用
Dapr 服务调用的工作原理
- 服务A 向服务B发起一个HTTP/gRPC的调用。调用转到了本地的Dapr sidecar
- Dapr使用名称解析组件发现服务B的位置
- Dapr 将消息转发至服务 B的 Dapr sidecar
- 服务B 的 Dapr sidecar将请求转发至服务B 上的特定端点 (或方法) 。 服务B 随后运行其业务逻辑代码
- 服务B 发送响应给服务A。 响应将转至服务B 的Dapr sidecar
- Dapr 转发响应至服务A 的 Dapr sidecar
- 服务 A 接收响应
注: Dapr sidecar之间的所有调用都通过gRPC来提高性能。 仅服务与 Dapr sidecar之间的调用可以是 HTTP或gRPC
注:Dapr sidecar使用可插入的名称解析组件来解析服务 B 的地址。在自托管模式下,Dapr 使用 mdns 来查找它。 在 Kubernetes 模式下运行时,由 Kubernetes DNS 服务决定地址。
关于自托管模式下的mDNS:
综上我们可以得知:
Dapr是通过向每个计算单元注入了一个Sidecar容器/进程,然后运用Sidecar与事件触发器进行交互,并通过标准HTTP或gRPC协议与计算单元进行通信的。
项目实战
我们在DaprClientWeb项目中增加两个接口分别用来请求ServiceA服务的/GetServiceA接口与ServiceB服务的/GetServiceB
同时需要在DaprClientWeb项目中引入Dapr.Client Nuget包
代码:
注意:此处DaprClient是从DaprClinetBuilder Build出来的
ServiceA
ServiceB
执行命令:
dapr run --app-id service-a --app-port 5001 dotnet run
dapr run --app-id service-b --app-port 5002 dotnet run
dapr run --app-id dapr-client-web --app-port 5003 dotnet run
查看效果:
然后我们通过DaprClientWeb项目 请求接口
到这里我们已经可以使用dapr进行服务之间的通信了。但是每次都需要通过dapr run 命令启动dapr sidecar这样岂不是太不优雅了,其中还包括几个APPID,DAPR_HTTP_PORT,AppPort,DAPR_GRPC_PORT需要管理,到时候服务一多肯定会十分头疼。其实这些问题都已经被一些大佬解决了,比如MASA团队就为此提供了很好地支持,我们只需在我们的项目中引入一个包就甚至可以通过一行代码就能够让项目轻松的使用Dapr了。
MASA DaprStarter
首先我们先在项目中引入 Masa.Contrib.Development.DaprStarter.AspNetCore
当前我用的版本是1.0.0-preview.22并且都在一直更新,还是比较稳定的,听说他们有全职的开源团队在维护与迭代,所以我们可以放心使用。
然后在各自项目的Program.cs中增加一行代码就可以了
builder.Services.AddDaprStarter(builder.Configuration.GetSection("DaprOptions"));
DaprClientWeb 示例:
当然需要在appsettings.Development.json文件中加入配置
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"DaprOptions": {
"AppId": "service-a",//不指定的话会自动根据AppId + AppIdDelimiter('-') + AppIdSuffix 规则生成
"AppPort": 5001,
"AppIdSuffix": "",//当前机器网卡地址
"DaprHttpPort": 8082,
"DaprGrpcPort": 8083
}
}
最后我们就只需直接启动项目就可以了,其他的就不用操心了。
看看效果:
细心的同学会发现这几个端口都变成我们在项目的appsettings.Development.json 文件中配置的了。
然后这里需要注意的是,这种用法只是在自托管模式下方便与本地开发调试使用,在生产环境上有基于k8s的另外一套用法,这里就不做多概述,感兴趣的同学可自行研究。
如果想了解 Masa.Contrib.Development.DaprStarter.AspNetCore 这个包的到底帮我们做了那些工作,可以去看看大佬的文章 一行代码让你的项目轻松使用Dapr
到此,基于dapr的服务调用已经差不多大功告成了,如果MASA的包用的爽了,记得去GitHub Star 一下。
赠人玫瑰,手留余香。
结尾
由于文章篇幅有限,涉及到知识内容也不是很深入,感兴趣的同学可以自行研究。
然后本文都是基于我的个人理解,然后也有参考官网以及大佬的文章和视频,文章如有什么不妥的地方欢迎指正,共同进步。后续有时间还会继续学习相关技术知识,欢迎Star与关注。感谢阅读!
源码地址
https://github.com/fengzhonghao8-24/Dapr.Example.git
.Net 7 轻松上手Dapr之服务调用的更多相关文章
- 手把手教你学Dapr - 4. 服务调用
上一篇:手把手教你学Dapr - 3. 使用Dapr运行第一个.Net程序 介绍 通过使用服务调用,您的应用程序可以使用标准的gRPC或HTTP协议与其他应用程序可靠.安全地通信. 为什么不直接用Ht ...
- Dapr微服务应用开发系列3:服务调用构件块
题记:这篇开始逐一深入介绍各个构件块,从服务调用开始 原理 所谓服务调用,就是通过这个构件块让你方便的通过HTTP或者gRPC协议同步调用其他服务的方法,这些方法也是通过HTTP或者gRPC来暴露的. ...
- Caller 服务调用 - Dapr
前言 上一篇我们讲了使用HttpClient的方式调用,那么如果我们现在需要更换为通过dapr实现服务调用,我们需要做哪些事情呢? Caller.Dapr 入门 如果我们的项目原本使用的是Caller ...
- 3. Caller 服务调用 - dapr
前言 上一篇我们讲了使用HttpClient的方式调用,那么如果我们现在需要更换为通过dapr实现服务调用,我们需要做哪些事情呢? Caller.Dapr 入门 如果我们的项目原本使用的是Caller ...
- dapr本地托管的服务调用体验与Java SDK的Spring Boot整合
1 简介 之前在文章<dapr入门与本地托管模式尝试>中介绍了dapr和本地托管,本文我们来介绍如果在代码中使用dapr的服务调用功能,并把它整合到Spring Boot中. Dapr服务 ...
- 技术分享:Dapr,让开发人员更轻松地构建微服务应用
最近一直在学习微服务相关的技术.微服务架构已成为构建云原生应用程序的标准,并且可以预见,到2022年,将有90%的新应用程序采用微服务架构.微服务架构提供了令人信服的好处,包括可伸缩性,松散的服务耦合 ...
- Dapr 客户端 搭配 WebApiClientCore 玩耍服务调用
使用Dapr 客户端 处理服务调用,需要遵循的他的模式,通常代码是这个样子的: var client = DaprClient.CreateInvokeHttpClient(appId: " ...
- Blazor+Dapr+K8s微服务之服务调用
1.1 Dapr环境配置 1.1.1 在开发机安装Docker Desktop并启用Kubernetes 安装过程略,安装好后效果如下:(左下角两个绿色指示Docker和 ...
- Dapr实战(二) 服务调用
服务调用是什么 在分布式应用程序中的服务之间进行调用会涉及到许多挑战. 例如: 维护其他服务的地址. 如何安全地调用服务. 在发生短暂的 暂时性错误 时如何处理重试. 分布式应用程序调用链路追踪. 服 ...
- Dapr初体验之服务调用
初次理解服务调用 在微服务中,有一个难点就是:如果你想使用各个服务组件,你就得知道不同服务的地址和端口,也就是服务发现. 在传统应用我们是怎么做的?就是在web项目里配置上api地址,如下: 在一个w ...
随机推荐
- xshell和xftp绿色版下载
下载地址:https://www.xshell.com/zh/free-for-home-school/ 点击后页面如下,输入自己的姓名和邮箱然后点击下载即可.登录自己的邮箱获取下载链接.
- 如何解决7z: command not found问题
7z是一种常见的压缩文件格式,如果你想要压缩或解压缩7z文件,你需要在你的系统上安装p7zip和p7zip-full.但是,有时候你会发现当你尝试运行7z或7za命令时,它会显示"bash: ...
- ByteArrayInputStream和ByteArrayOutputStream不需要关闭流的原理--博客摘录
---------------- 版权声明:本文为CSDN博主「PSUUGDUFNM」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明.原文链接:https://blo ...
- Oracle学习-----基本SQL select语句
一.基本select语句 SELECT 标识 选择那些列 FROM 标识从哪个表中选择 select * 标识 全部选择 select department_id, location_id ...
- shell脚本基本介绍
1.编程介绍 驱动 硬件默认是不能使用的 CPU控制硬件.不同的厂家硬件设备之间需要进行指令沟通,我们需要驱动程序来进行"翻译": 更趋近与开发的工程师,要学习"汇编语言 ...
- 面向对象的练习总结(java)
三次作业总结博客 l 前言 第一次题目集是我刚刚接触java所做的第一套习题,本次题目难度不大,题量较多,涉及的知识点主要是基础的语法知识,出题人的意图是让我们尽快熟悉java的语法,由于事先有c语 ...
- 位运算与MOD快速幂详细知识点
最近写的一些题目设计到了数论的取模 如下题 链接:https://ac.nowcoder.com/acm/contest/3003/G来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制: ...
- JavaWeb学习--EL表达式
一.EL表达式: 1.命令表达式: ${作用域对象别名.共享数据} 2.命令作用: 1)EL表达式是EL工具包提供一种特殊命令格式[表达式命令格式] 2)EL表达式在JSP文件上使用 3)负责在JSP ...
- for in循环的坑
num本来数个数组,但是for in把数组原型上的也遍历(偶尔会)记录一下坑,数组还是for循环,for in还是用在对象上好
- linux 安装 jupyter notebook
虚拟机使用的是ubuntu系统 直接遇见一个问题 E: 无法获得锁 /var/lib/dpkg/lock - open (11: 资源暂时不可用) E: 无法锁定管理目录(/var/lib/dpkg/ ...