前言

对于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. TypeScript系列 -> 遇到报错 Cannot find name ‘console‘. Do you need to change your target library?ging the ‘lib‘ compiler option

    学习ts遇到的报错 Cannot find name 'console'. Do you need to change your target library?ging the 'lib' compi ...

  2. uniapp里面设置onlaunch以后在加载页面调接口

    main.js 里面 Vue.prototype.$onLaunched = new Promise(resolve => { Vue.prototype.$isResolve = resolv ...

  3. Java8中Stream的用法

    Java8中Stream的用法 1.概述 Stream APl ( java.util.stream)把真正的函数式编程风格引入到Java中.这是目前为止对Java类库最好的补充,因为Stream A ...

  4. api接口基础Day2

    精华笔记: 正则表达式: 用于描述字符串的内容格式,使用它通常用于匹配一个字符串是否符合格式要求 正则表达式的语法:-------------了解.不用纠结.不用深入研究 1.[]:表示一个字符,该字 ...

  5. 关于uniapp图片默认的空隙处理方案

    display:block; 或者 display:flex;

  6. vue引入多个指令文件

    单个指令引入,在main.js(入口JS文件)中引入你已经写好的指令文件,可以省略文件后缀: // main.js import focus from 'xxx/directive'多个指令引入 Vu ...

  7. Flutter安装SDK及配置

    一.下载SDK 1.官网下载 https://docs.flutter.dev/development/tools/sdk/releases?tab=macos 2.git下载 git clone h ...

  8. 艾思最新案例分享:塔蓝物流app-物流仓储管理系统app. app开发

    塔蓝物流app是一款物流仓储管理app:主要业务范围空运,海运,进出口货物及过境货物的运输代理,包括揽物订舱,仓储(危险品除外),包装,搬运装卸,中转,流通加工,集装箱拼装拆箱(危险品除外),结算运杂 ...

  9. Ubuntu系统Root用户无法登录解决办法

    默认 系统 root 登录 图形界面,出现 登录失败.解决方法如下: 1,登录普通用户, 打开终端执行命令, 使用su root或sudo -i切换到root用户(必须) su root 按照提示输入 ...

  10. liunx服务器搭建jenkins环境

    服务器搭建jenkins 持续集成环境(1)-Jenkins安装 1)安装JDK Jenkins需要依赖JDK,所以先安装JDK1.8 yum install java-1.8.0-openjdk* ...