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

介绍

通过使用服务调用,您的应用程序可以使用标准的gRPC或HTTP协议与其他应用程序可靠、安全地通信。

为什么不直接用HttpClientFactory呢

先问几个问题:

  • 如何发现和调用不同服务的方法

  • 如何安全地调用其他服务,并对方法应用访问控制

  • 如何处理重试和瞬态错误

  • 如何使用分布式跟踪指标来查看调用图来诊断生产中的问题

此时你会发现这些事情HttpClientFactory没有帮你完成,而在微服务中这些又是必不可少的能力,接下来看看服务调用都做了什么

服务调用如何工作的

先看一下两个服务之间的调用顺序

55078ce2a7feab47b0d8b8529c803201.png

  1. 服务A 向服务B发起一个HTTP/gRPC的调用。调用转到了本地的Dapr sidecar

  2. Dapr使用名称解析组件发现服务B的位置

  3. Dapr 将消息转发至服务 B的 Dapr sidecar

    : Dapr sidecar之间的所有调用都通过gRPC来提高性能。仅服务与 Dapr sidecar之间的调用可以是 HTTP或gRPC

  4. 服务B 的 Dapr sidecar将请求转发至服务B 上的特定端点 (或方法) 。服务B 随后运行其业务逻辑代码

  5. 服务B 发送响应给服务A。响应将转至服务B 的Dapr sidecar

  6. Dapr 转发响应至服务A 的 Dapr sidecar

  7. 服务 A 接收响应

命名空间作用域

默认情况下,调用同一个命名空间的其他服务可以直接使用AppID(假设是:nodeapp)

localhost:3500/v1.0/invoke/nodeapp/method/neworder

服务调用也支持跨命名空间调用,在所有受支持的宿主平台上,Dapr AppID遵循FQDN格式,其中包括目标命名空间。

FQDN:(Fully Qualified Domain Name)全限定域名:同时带有主机名和域名的名称。(通过符号“.”)

例如:主机名是bigserver,域名是mycompany.com,那么FQDN就是bigserver.mycompany.com

   注:FQDN是通过符号.来拼接域名的,这也就解释了AppID为什么不能用符号.,这里不记住的话,应该会有不少小伙伴会踩坑

           比如.net开发者习惯用 A.B.C 来命名项目,但AppID需要把.换成-且所有单词最好也变成小写 (a-b-c),建议把它变成约定遵守

比如调用命名空间:production,AppID:nodeapp

localhost:3500/v1.0/invoke/nodeapp.production/method/neworder

这在K8s集群中的跨名称空间调用中特别有用  

服务间安全性

通过托管平台上的相互(mTLS)身份验证,包括通过Dapr Sentry服务的自动证书转移,可以确保Dapr应用程序之间的所有调用的安全。下图显示了自托管应用程序的情况。

访问控制

应用程序可以控制哪些其他应用程序可以调用它们,以及通过访问策略授权它们做什么。这使您能够限制具有个人信息的敏感应用程序不被未经授权的应用程序访问,并结合服务到服务的安全通信,提供了软多租户部署。 

具体的访问控制后续章节会介绍

重试

在调用失败和瞬态错误的情况下,服务调用执行自动重试,并在回退时间段内执行。

注:自动重试,默认是开启的,可以关。但如果不关且业务又不支持幂等是很危险的。建议服务的接口要设计支持幂等,这在微服务里也是一个标配的选择。

导致重试的错误有:  

网络错误,包括端点不可用和拒绝连接。 

由于在调用/被调用的Dapr sidecars上更新证书而导致的身份验证错误。 

每次呼叫重试的回退间隔为1秒,最多为3次。通过gRPC与目标Sidecar连接的超时时间为5秒

可插拔的服务发现

Dapr可以在各种托管平台上运行。为了启用服务发现和服务调用,Dapr使用可插拔的名称解析组件。例如,K8s名称解析组件使用K8s DNS服务来解析集群中运行的其他应用程序的位置。自托管机器可以使用mDNS名称解析组件。Consul名称解析组件可以在任何托管环境中使用,包括K8s或自托管环境

划重点,自托管机器使用mDNS,在开发环境中后面文章会推荐VS上的无缝开发体验,就是基于mDNS的

但它有点点小问题,我们已经解决了。你只需要像开发一个控制台程序一样,基于Minimal API开心的F5就可以了

建议还没有了解Minimal API的小伙伴可以研究起来了,真香

使用mDNS进行轮询负载均衡

一图胜千言,就使用mDNS轮着调用

965201ae0fdd8cc022a2a3784ec08e19.png

可观测性的跟踪和指标

默认情况下,将跟踪应用程序之间的所有调用,并收集指标,以提供应用程序的洞察力和诊断,这在生产场景中尤其重要。这为您提供了服务之间调用的调用图和指标。 

服务调用API和gRPC代理

pythonapp 通过Dapr sidecar调用nodeapp,通过服务调用的API及gRPC代理依然是上面见到的那个调用流程,做到了语言无关

46160ac985cb59bef3879ba87bf47151.png

使用HTTP调用服务

创建Assignment.Server

创建ASP.NET Core空项目,并修改launchSettings.json,让启动HTTP的启动端口变为5000

profiles.Assignment.Server.applicationUrl 的值改为 "https://localhost:6000;http://localhost:5000"

修改Program.cs文件

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();app.MapPost("/", () => Console.WriteLine("Hello!"));app.MapGet("/Hello1", () =>
{Console.WriteLine("Hello World1!");return $"\"Hello World1!\"";
});app.MapPost("/Hello2", () => Console.WriteLine("Hello World2!"));app.Map("/Hello3", () => Console.WriteLine("Hello World3!"));app.Run();

此时一共有4个服务

  • / :Post方法,打印Hello!

  • /Hello1:Get方法,打印Hello World1!,返回Hello World1!

    注:返回的类型要是Json字符串,方便SDK反序列化

  • /Hello2:Post方法,打印Hello World2!

  • /Hello3:不带后缀表示适配所有方法,打印Hello World3!

先使用Dapr CLI来验证一下

运行Assignment.Server:在目录dapr-study-room\Assignment04\Assignment.Server打开命令行工具,并执行下面命令

dapr run --app-id assignment-server --app-port 5000 dotnet watch

细心的小伙伴应该可以发现与上一篇的命令有一点点不同,dontet run变成了dotnet watch,这样会开启热重载,方便调试

调用服务:再打开一个新的命令行工具,并执行下面命令

dapr invoke --app-id assignment-server --method /
dapr invoke --app-id assignment-server --method Hello1
dapr invoke --app-id assignment-server --method Hello2
dapr invoke --app-id assignment-server --method Hello3

可以发现4个命令都调用成功了,但是Assignment.Server输出结果有点意外

== APP == Hello!
== APP == Hello World2!
== APP == Hello World3!

是的,没有Hello World1!,那怎么办呢?我们把Hello1的命令改一下

dapr invoke --app-id assignment-server --method Hello1 --verb GET

invoke调用的输出除了App invoked successfully以外还多了一行Hello World1!

与此同时Assignment.Server的输出正确了

== APP == Hello World1!

除此之外invoke还有一些参数,比如--data,--data-file,喜欢研究Dapr CLI的小伙伴可以继续尝试。不过一般情况下用SDK就可以了

创建Assignment.Client

HTTP服务调用

创建控制台应用程序项目,使用NuGet包管理器添加Dapr.Client SDK,并修改Program.cs文件

using Dapr.Client;var appId = "assignment-server";var client = new DaprClientBuilder().Build();await client.InvokeMethodAsync(appId, "/");var resp = await client.InvokeMethodAsync<string>(HttpMethod.Get, appId, "Hello1");
Console.WriteLine($"Hello1 Response: {resp}");await client.InvokeMethodAsync(appId, "Hello2");await client.InvokeMethodAsync(appId, "Hello3");

看几个细节

  • DaprClient是从DaprClinetBuilder Build出来的

    还有一种方式使用DaprClient,通过DI

    首先都是需要添加Dapr.AspNetCore NuGet包

    然后开始有分支了,如果是以前Web API的方式可以在Startup.cs文件ConfigureServices方法加入一行代码

    services.AddControllers().AddDapr();

    如果使用Minimal API默认是没有Controllers的,那可以在var builder = WebApplication.CreateBuilder(args); 之后加入一行代码

    builder.Services.AddDaprClient();

    成功的注入进来了,在构造函数或者[FromServices]里愉快的玩耍吧

  • HttpMethod.Post 的我都没有指定,默认就是Post

  • HttpMethod.Get的时候,返回值会自动用Json反序列化

    不喜欢Json?可以通过 DaprClient.CreateInvokeHttpClient 构造 HttpClient,聪明的你肯定知道后面怎么办了

注:

  1. Minimal API虽香,但新,所以不是所有功能都支持,比如从参数中直接映射状态管理,要等Minimal API支持Model Binder以后且SDK也同步支持了才可以

  2. DaprClient是TCP的,也是线程安全的,可以大胆的复用,如果不用DI的话不需要频繁构建DaprClient

验证调用成功

使用命令行工具打开目录dapr-study-room\Assignment04\Assignment.Client,然后执行命令

dotnet run

如果你不是用VS Code终端的PowerShell执行dapr run就可能遇到下面的错误

即便你没有遇到也建议了解一下如何支持非默认端口

An exception occurred while invoking method: '/' on app-id: 'assignment-server'---> System.Net.Http.HttpRequestException: 由于目标计算机积极拒绝,无法连接。 (127.0.0.1:3500)---> System.Net.Sockets.SocketException (10061): 由于目标计算机积极拒绝,无法连接。

因为上面使用dapr run的时候没有指定dapr http port,而默认client访问的是3500端口

解决的办法有两种:

  1. 修改Assignment.Server启动参数,增加--dapr-http-port 3500,这个方法治标不治本,因为将来我们可能启动多个服务

    dapr run --app-id assignment-server --app-port 5000 --dapr-http-port 3500 dotnet watch
  2. 修改Assignment.Client的环境变量

    首先执行dapr list查看端口,以下面为例,HTTP PORT是51460

    APP ID             HTTP PORT  GRPC PORT  APP PORT  COMMAND       AGE  CREATED              PID

    assignment-server  51460      51461      5000      dotnet watch  7s   2021-10-29 14:13.49  11676

    修改Assignment.Client的启动参数,注意把51460换成你自己的端口,使用PowerShell执行下面命令

    $Env:DAPR_HTTP_PORT = 51460
    dotnet run

再执行一次dotnet run就可以看到正确的输出结果了

Hello1 Response: Hello World1!

gRPC服务调用

篇幅太长了,举一反三吧。就是调用InvokeMethodGrpcAsync,然后dapr-http-port换成dapr-grpc-port,DAPR_HTTP_PORT换成DAPR_GRPC_PORT

查看跟踪

还记得dapr init的时候docker里有个zipkin吧,通过zipkin可以看一下调用跟踪,通过浏览器打开下面地址

http://localhost:9411/

此时页面是空的

4a9530bc8657b8d59b78cfdc151b850d.png

根据步骤操作一下就可以看到了

9c0ba17e1c12c3fd276f60b0a936ffc9.png

随便点开一行数据尾部的SHOW,就可以看到调用详情

5b06dc7b825fe37bb70b03a457b2d32d.png

本章源码

Assignment04

https://github.com/doddgu/dapr-study-room

我们正在行动,新的框架、新的生态

我们的目标是自由的易用的可塑性强的功能丰富的健壮的

所以我们借鉴Building blocks的设计理念,正在做一个新的框架MASA Framework,它有哪些特点呢?

  • 原生支持Dapr,且允许将Dapr替换成传统通信方式

  • 架构不限,单体应用、SOA、微服务都支持

  • 支持.Net原生框架,降低学习负担,除特定领域必须引入的概念,坚持不造新轮子

  • 丰富的生态支持,除了框架以外还有组件库、权限中心、配置中心、故障排查中心、报警中心等一系列产品

  • 核心代码库的单元测试覆盖率90%+

  • 开源、免费、社区驱动

  • 还有什么?我们在等你,一起来讨论

经过几个月的生产项目实践,已完成POC,目前正在把之前的积累重构到新的开源项目中

目前源码已开始同步到Github(文档站点在规划中,会慢慢完善起来):

MASA.BuildingBlocks

MASA.Contrib

MASA.Utils

MASA.EShop

BlazorComponent

MASA.Blazor

QQ群:7424099

微信群:加技术运营微信(MasaStackTechOps),备注来意,邀请进群

a61efaa2378e12c938723bbb91390f72.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/295758.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高速的二舍八入三七作五_有没有发现,高速收费都是5的倍数,这是为什么?怎么判断的?...

要想富&#xff0c;先修路。这是劳动人民致富的第一要素。从最早的泥巴路到现在的高速公路&#xff0c;人民生活有了翻天覆地的变化。随后路上汽车的数量也就越来越多了&#xff0c;堵车便成为很常见的现象&#xff0c;所以就有了高架桥、立交桥的诞生&#xff0c;它们的出现很…

清华大学再出神人,汽车被盗,用“贪心算法”瞬间找到偷车贼

全世界只有3.14 % 的人关注了爆炸吧知识惹谁都不要惹会算法的人今天要讲的故事的主人公&#xff0c;是来自圣母大学计算机系的副教授史戈宇。就在之前&#xff0c;他还经历了一场惊心动魄的劫车事件。度假旅游遇劫匪在某一个周末&#xff0c;史教授计划着开车带一家人去百慕大度…

Android之RecyclerView 实现真正的Gallery效果

简介&#xff1a; RecyclerView是support-v7包中的新组件&#xff0c;是一个强大的滑动组件&#xff0c;与经典的ListView相比&#xff0c;同样拥有item回收复用的功能&#xff0c;但是直接把viewholder的实现封装起来&#xff0c;用户只要实现自己的viewholder就可以了&#x…

手把手教你学Dapr - 2. 必须知道的概念

Sidecar 边车Dapr API提供Http和gRPC两种通讯方式。运行方式则可以是容器也可以是进程&#xff08;Windows开发推荐使用Self Hosted&#xff0c;后续会解释&#xff09;。这样的好处是与运行环境无关&#xff0c;且独立运行不需要应用包含Dapr运行时的代码。只需要通过SDK集成即…

office打开服务器文件提示内存不足,打开Excel2016提示内存或磁盘空间不足的解决方法...

摘要在Excel2016或者2013中打开新建的空白文档提示&#xff1a;内存或磁盘空间不足&#xff0c;Microsoft Excel无法再次打开或保存任何文档。问题描述在Excel2016或者2013中打开新建的空白文档提示&#xff1a;内存或磁盘空间不足&#xff0c;Microsoft Excel无法再次打开或保…

模块化 JS Ajax 请求

为什么80%的码农都做不了架构师&#xff1f;>>> 现在有一个需求&#xff0c;点击 Button需要调用一个函数获取 JSON 数据传给 artTemplate 模板渲染生成页面&#xff0c;所以需要在这个函数中封装原生的 JS Ajax&#xff0c;同时重新渲染页面。 Arttemplate 模板 &…

女孩子胸前的秘密,研究三天后我出不来了……

全世界只有3.14 % 的人关注了爆炸吧知识前两天&#xff0c;知识君写了一篇关于胸大女生烦恼的科普文。忍“乳”负重&#xff0c;身材好的女孩子究竟有多不容易&#xff1f;我从科学的角度算出来了……你们居然觉得我有写广告的嫌疑&#xff1f;那就真的是让知识君觉得太委屈了&…

为什么ps图片打开是色块_PS教程 我的PS我做主之山村调色

执行【文件】|【打开】命令&#xff0c;打开原稿图像打开“图层”面板&#xff0c;按两次键盘上的快捷键“CtrlJ”复制背景层&#xff0c;得到图层1、图层1副本3. 打开“通道”面板&#xff0c;选取蓝通道&#xff0c;如图执行【图像】|【应用图像】命令&#xff0c;打开“应用…

EVGA Precision—— 显卡超频神器 可用于调节风扇转速 降温

EVGA Corporation&#xff0c;总部在美国&#xff0c;美国最大板卡公司之一&#xff0c;是Nvidia的核心合作伙伴。 EVGA Precision X是一个可以满足用户对显卡所有需求的软件。它可以让我们调节显卡的风扇转速、时钟速度以及电压等。 系统要求 微软Windows 8/7/Vista/XPGeForce…

ftp服务器新建虚拟目录,ftp服务器 虚拟目录

ftp服务器 虚拟目录 内容精选换一换下载地址&#xff1a;https://github.com/gmarcais/Jellyfish/releases/download/v2.2.10/jellyfish-2.2.10.tar.gz下载地址&#xff1a;http://ftp.1000genomes.ebi.ac.uk/vol1/ftp/technical/reference/human_g1k_vftp服务器 虚拟目录 相关…

精彩回顾 | Dapr闪电说系列

点击蓝字关注我们微软 Reactor 为帮助广开发者&#xff0c;技术爱好者&#xff0c;更好的学习 .NET Core, C#, Python&#xff0c;数据科学&#xff0c;机器学习&#xff0c;AI&#xff0c;区块链, IoT 等技术&#xff0c;将每周三到周六&#xff0c;组织 3~5 场线上分享活动。…

地球不是圆的,别让教科书限制了孩子的想象力!

全世界只有3.14 % 的人关注了爆炸吧知识我们在科学课上应该学过宇宙很大地球只是宇宙中微不足道的一个小星球虽然诺达的宇宙我们还没怎么探索但你对地球又了解多少呢&#xff1f;我们眼睛所见的我们所知的其实也都只是非常微不足道的一部分今天炸炸就带你来深入了解关于地球鲜为…

三维重建 几何方法 深度学习_基于深度学习的视觉三维重建研究总结

三维重建意义三维重建作为环境感知的关键技术之一&#xff0c;可用于自动驾驶、虚拟现实、运动目标监测、行为分析、安防监控和重点人群监护等。现在每个人都在研究识别&#xff0c;但识别只是计算机视觉的一部分。真正意义上的计算机视觉要超越识别&#xff0c;感知三维环境。…

Codeforces Round #174 (Div. 2) Cows and Primitive Roots(数论)

Cows and Primitive Roots time limit per test2 secondsmemory limit per test256 megabytesinputstandard inputoutputstandard outputThe cows have just learned what a primitive root is! Given a prime p, a primitive root is an integer x (1 ≤ x < p) such …

Android之SlidingMenu使用和总结

SlidingMenu使用和总结 我们经常看到手机QQ和酷狗主界面里面都有侧滑菜单的使用,今天我们在这里介绍怎么使用SlidingMenu的使用和总结,SlingMenu是开源的,不说了多了,先爆照 第一步:下源码 // 下载 ZXing 项目源码 https://github.com/jfeinstein10/SlidingMenu …

如何让你的碎片化时间更有价值?

全世界只有3.14 % 的人关注了爆炸吧知识不知道大家有没有发现&#xff0c;我们开始变得浮躁起来了&#xff0c;我们不再愿意花大量时间去做成一件事情&#xff0c;也无法下定决心&#xff0c;改变自己糟糕的现状。却羡慕着手机屏幕里各种各样的成功人士&#xff0c;活出了自己最…

窥探Swift编程之强大的Switch

之前初识Swift中的Switch语句时&#xff0c;真的是让人眼前一亮&#xff0c;Swift中Switch语句有好多特有而且特好用的功能。说到Switch, 只要是写过程序的小伙伴对Switch并不陌生。其在程序中的出镜率还是比较高档。Switch属于程序的分支语句&#xff0c;Switch的功能便于处理…

安富莱v6开发板网口通讯_安富莱嵌入式周报第170期:2020.07.202020.07.26

说明&#xff1a;谢谢大家的关注&#xff0c;继续为大家盘点上周精彩内容。1、沁恒推出带USB3.0&#xff0c;千兆以太网&#xff0c;光纤接口的RISC内核单片机CH569 CH569/565 微控制器使用 RISC-V3A 内核&#xff0c; 支持 RISC-V 指令的 IMAC 子集。片上集成超高速USB3.0主…

连续子数组的最大和

有一个整数数组&#xff0c;求出连续子数组的和的最大值。有一个首尾相连的整数数组&#xff0c;求出连续子数组的和的最大值。在数组中&#xff0c;数字减去它右边的数字得到一个数对之差。求所有数对之差的最大值。1、思路&#xff1a; 动态规划思路&#xff1a;用函数f(i)表…

WPF中设置了WindowStyle=None后,窗口仍然有边框的解决方法

1. 设置了窗体的WindowStyle"None",窗口还是右边框&#xff0c;如下图&#xff1a; 2. 这是因为窗体默认是可以改变大小的&#xff0c;所以需要修改ResizeMode的值 ResizeMode"NoResize", 这样设置后&#xff0c;上图中的边框就没有了