前言

对于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初始化包括:

  1. 运行Redis 容器实例以用作本地状态存储和消息代理。
  2. 运行Zipkin 容器实例以实现可观察性。
  3. 使用上述组件定义创建默认组件文件夹。
  4. 运行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与两个服务端项目-ServiceAServiceB

然后先在两个服务端项目中分别增加一个测试接口
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来分别请求ServiceAServiceB的接口 演示Dapr的服务调用。

Dapr 服务调用

Dapr 服务调用的工作原理

  1. 服务A 向服务B发起一个HTTP/gRPC的调用。调用转到了本地的Dapr sidecar
  2. Dapr使用名称解析组件发现服务B的位置
  3. Dapr 将消息转发至服务 B的 Dapr sidecar
  4. 服务B 的 Dapr sidecar将请求转发至服务B 上的特定端点 (或方法) 。 服务B 随后运行其业务逻辑代码
  5. 服务B 发送响应给服务A。 响应将转至服务B 的Dapr sidecar
  6. Dapr 转发响应至服务A 的 Dapr sidecar
  7. 服务 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之服务调用的更多相关文章

  1. 手把手教你学Dapr - 4. 服务调用

    上一篇:手把手教你学Dapr - 3. 使用Dapr运行第一个.Net程序 介绍 通过使用服务调用,您的应用程序可以使用标准的gRPC或HTTP协议与其他应用程序可靠.安全地通信. 为什么不直接用Ht ...

  2. Dapr微服务应用开发系列3:服务调用构件块

    题记:这篇开始逐一深入介绍各个构件块,从服务调用开始 原理 所谓服务调用,就是通过这个构件块让你方便的通过HTTP或者gRPC协议同步调用其他服务的方法,这些方法也是通过HTTP或者gRPC来暴露的. ...

  3. Caller 服务调用 - Dapr

    前言 上一篇我们讲了使用HttpClient的方式调用,那么如果我们现在需要更换为通过dapr实现服务调用,我们需要做哪些事情呢? Caller.Dapr 入门 如果我们的项目原本使用的是Caller ...

  4. 3. Caller 服务调用 - dapr

    前言 上一篇我们讲了使用HttpClient的方式调用,那么如果我们现在需要更换为通过dapr实现服务调用,我们需要做哪些事情呢? Caller.Dapr 入门 如果我们的项目原本使用的是Caller ...

  5. dapr本地托管的服务调用体验与Java SDK的Spring Boot整合

    1 简介 之前在文章<dapr入门与本地托管模式尝试>中介绍了dapr和本地托管,本文我们来介绍如果在代码中使用dapr的服务调用功能,并把它整合到Spring Boot中. Dapr服务 ...

  6. 技术分享:Dapr,让开发人员更轻松地构建微服务应用

    最近一直在学习微服务相关的技术.微服务架构已成为构建云原生应用程序的标准,并且可以预见,到2022年,将有90%的新应用程序采用微服务架构.微服务架构提供了令人信服的好处,包括可伸缩性,松散的服务耦合 ...

  7. Dapr 客户端 搭配 WebApiClientCore 玩耍服务调用

    使用Dapr 客户端 处理服务调用,需要遵循的他的模式,通常代码是这个样子的: var client = DaprClient.CreateInvokeHttpClient(appId: " ...

  8. Blazor+Dapr+K8s微服务之服务调用

    1.1         Dapr环境配置 1.1.1        在开发机安装Docker Desktop并启用Kubernetes 安装过程略,安装好后效果如下:(左下角两个绿色指示Docker和 ...

  9. Dapr实战(二) 服务调用

    服务调用是什么 在分布式应用程序中的服务之间进行调用会涉及到许多挑战. 例如: 维护其他服务的地址. 如何安全地调用服务. 在发生短暂的 暂时性错误 时如何处理重试. 分布式应用程序调用链路追踪. 服 ...

  10. Dapr初体验之服务调用

    初次理解服务调用 在微服务中,有一个难点就是:如果你想使用各个服务组件,你就得知道不同服务的地址和端口,也就是服务发现. 在传统应用我们是怎么做的?就是在web项目里配置上api地址,如下: 在一个w ...

随机推荐

  1. MySQL事务MVCC、undolog和redolog

    MySql的MVCC多版本控制 undolog:回滚日志(保证一致性)只有在ReadCommited和RepeatableRead隔离级别有用 redolog:重写日志(保证持久性) 示例讲解 Rea ...

  2. Hive+spark工业化项目

    DolphinScheduler:国产调度平台 airflow: 调度平台

  3. spring security添加接口白名单

    在项目中遇到的问题是要将某个接口设为白名单,无需验证即可被用户使用. 解决方法: 在nacos配置文件中ignore whites(不校验白名单)中添加对应接口,无gateway前缀即可,添加立即生效 ...

  4. centos7 redis 无法用 systemctl 启动

    今天刚安装了redis,修改了 /etc/redis.conf 的内容. 尝试在 bind 后添加一个地址 "bind 127.0.0.1 -::* 192.168.2.1", 后 ...

  5. jquery的ajax方法获取不到return返回值

    /** 2 * 方式:(1)同步调用 (2)在ajax函数中return值 3 * 结果:返回 1.未成功获取返回值 4 * 失败原因:ajax内部是一个或多个定义的函数,ajax中return返回值 ...

  6. 修改word文档中已有的批注者名称

    前言 https://blog.csdn.net/hyh19962008/article/details/89430548 word中可以通过修改用户的信息实现新建的批注者显示不同的名称,但是对于文档 ...

  7. SpringCloud之旅

    现在大部分公司的项目架构都选择了微服务,我们公司也不例外,那么什么是微服务呢?今天就来开启SpringCloud之旅! SpringCloud是基于SpringBoot的一整套的微服务架构.他提供了微 ...

  8. 前端复习之DOM、BOM

    BOM VS DOM: 1 BOM:浏览器对象模型(API),专门操作浏览器窗口的API 2 没标准! 3 DOM:文档对象模型(API),专门操作网页内容的API 4 可以对网页中任意对象,做任意修 ...

  9. C语言声明与定义的区别

    转自:https://blog.csdn.net/gatieme/article/details/50640424 C++程序通常由许多文件组成,为了让多个文件访问相同的变量,C++区分了声明和定义. ...

  10. Python之常用数据类型详解

    tuple 元组 1 # 定义 2 temp = (2, ) # 规范定义,单个元素的元组 3 tem = 2, # 可行,但不规范定义 4 tep = () # 空元组 5 6 tp = (1, ' ...