前言

 上一篇对Dapr进行了了解,并搭建了Dapr环境。接下来就对Dapr的各个构建块类型的了解、应用实际案例。

一、服务调用:

 在许多具有多个需要相互通信的服务的环境中,都会面临着很多问题。 如:

  • 维护其他服务的地址
  • 如何安全地调用服务。
  • 在发生短暂的 暂时性错误 时如何处理重试
  • 分布式应用程序调用链路追踪

 服务调用构建块通过使用 Dapr 挎斗作为服务的 反向代理 来解决这些难题。

 调用逻辑:

 服务调用就是应用程序可以使用 gRPC 或 HTTP 这样的标准协议来发现并可靠地与其他应用程序通信。

 Dapr的服务调用如何工作的总览图,如下:

 

  1. 服务 A 对服务 B 发起HTTP/gRPC的调用。

  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 的Sidecar。

  6. Dapr 将消息转发至服务 A 的 Dapr Sidecar。

  7. 服务 A 接收响应。

 服务调用特性:

  由于调用经过Sidecar,Dapr 可以注入一些有其他行为:

  • 失败时自动重试调用。
  • 通过相互 (mTLS) 身份验证(包括自动证书滚动更新),在服务之间进行调用。
  • 使用访问控制策略控制客户端可以执行的操作。
  • 捕获服务间所有调用的跟踪和指标,以提供分布式调用链路追踪与诊断。

二、调用示例:

 1、创建两个项目:DaprFrontEnd(前端示例)、DaprBackEnd(后端示例)

  DaprFrontEnd项目:Razor项目用于展示从后端示例中调用结果内容

  DaprBackEnd项目:Api项目用于获取数据

  

 2、DaprFrontEnd项目调整运行:

  a) 修改绑定端口:

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.UseUrls("http://0.0.0.0:8220");
});

  b)使用Dapr cli 命令启动项目:

//dapr命令
dapr run --dapr-http-port 3511 --app-port 5000 --app-id backend dotnet .\DaprBackEnd.dl //输出结果
Starting Dapr with id backend. HTTP Port: 3511. gRPC Port: 1030
time="2021-10-24T19:00:48.5801709+08:00" level=info msg="starting Dapr Runtime -- version 1.4.3 -- commit a8ee30180e1183e2a2e4d00c283448af6d73d0d0" app_id=backend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:00:48.5831673+08:00" level=info msg="log level set to: info" app_id=backend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:00:48.5890733+08:00" level=info msg="metrics server started on :1033/" app_id=backend instance=Coder scope=dapr.metrics type=log ver=1.4.3
time="2021-10-24T19:00:48.6178099+08:00" level=info msg="standalone mode configured" app_id=backend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:00:48.6178272+08:00" level=info msg="app id: backend" app_id=backend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:00:48.6205808+08:00" level=info msg="mTLS is disabled. Skipping certificate request and tls validation" app_id=backend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:00:48.6835042+08:00" level=info msg="local service entry announced: backend -> 192.168.0.109:1038" app_id=backend instance=Coder scope=dapr.contrib type=log ver=1.4.3
time="2021-10-24T19:00:48.6835042+08:00" level=info msg="Initialized name resolution to mdns" app_id=backend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:00:48.6855038+08:00" level=info msg="loading components" app_id=backend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:00:48.7225025+08:00" level=info msg="component loaded. name: pubsub, type: pubsub.redis/v1" app_id=backend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:00:48.7228271+08:00" level=info msg="waiting for all outstanding components to be processed" app_id=backend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:00:48.7310234+08:00" level=info msg="component loaded. name: statestore, type: state.redis/v1" app_id=backend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:00:48.732082+08:00" level=info msg="all outstanding components processed" app_id=backend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:00:48.7374914+08:00" level=info msg="enabled gRPC tracing middleware" app_id=backend instance=Coder scope=dapr.runtime.grpc.api type=log ver=1.4.3
time="2021-10-24T19:00:48.7384898+08:00" level=info msg="enabled gRPC metrics middleware" app_id=backend instance=Coder scope=dapr.runtime.grpc.api type=log ver=1.4.3
time="2021-10-24T19:00:48.7434866+08:00" level=info msg="API gRPC server is running on port 1030" app_id=backend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:00:48.7444869+08:00" level=info msg="enabled metrics http middleware" app_id=backend instance=Coder scope=dapr.runtime.http type=log ver=1.4.3
time="2021-10-24T19:00:48.7444869+08:00" level=info msg="enabled tracing http middleware" app_id=backend instance=Coder scope=dapr.runtime.http type=log ver=1.4.3
time="2021-10-24T19:00:48.7464879+08:00" level=info msg="http server is running on port 3511" app_id=backend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:00:48.7464879+08:00" level=info msg="The request body size parameter is: 4" app_id=backend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:00:48.7474861+08:00" level=info msg="enabled gRPC tracing middleware" app_id=backend instance=Coder scope=dapr.runtime.grpc.internal type=log ver=1.4.3
time="2021-10-24T19:00:48.7474861+08:00" level=info msg="enabled gRPC metrics middleware" app_id=backend instance=Coder scope=dapr.runtime.grpc.internal type=log ver=1.4.3
time="2021-10-24T19:00:48.7484875+08:00" level=info msg="internal gRPC server is running on port 1038" app_id=backend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:00:48.7494884+08:00" level=info msg="application protocol: http. waiting on port 5000. This will block until the app is listening on that port." app_id=backend instance=Coder scope=dapr.runtime type=log ver=1.4.3
Updating metadata for app command: dotnet .\DaprBackEnd.dll
You're up and running! Both Dapr and your app logs will appear here. == APP == info: Microsoft.Hosting.Lifetime[0]
== APP == Now listening on: http://0.0.0.0:8220
== APP == info: Microsoft.Hosting.Lifetime[0]
== APP == Application started. Press Ctrl+C to shut down.
== APP == info: Microsoft.Hosting.Lifetime[0]
== APP == Hosting environment: Production
== APP == info: Microsoft.Hosting.Lifetime[0]
== APP == Content root path: F:\coding\DaprMultiContainer\DaprBackEnd\bin\Debug\netcoreapp3.1

 3、DaprBackEnd项目调整:

  a) 修改端口

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.UseUrls("http://0.0.0.0:8230");
});

  b) 添加Dapr.AspNetCore包

Install-Package Dapr.AspNetCore

  c) 注入Dapr

public void ConfigureServices(IServiceCollection services)
{
services.AddControllers().AddDapr();
services.AddRazorPages();
}

  d) 调用DaprBackEnd 服务接口:

public class IndexModel : PageModel
{
private readonly DaprClient _daprClient; public IndexModel(DaprClient daprClient)
{
_daprClient = daprClient ?? throw new ArgumentNullException(nameof(daprClient));
} public async Task OnGet()
{
//方式一:使用HttpClient
//using var httpClient = DaprClient.CreateInvokeHttpClient();
//var result = await httpClient.GetAsync("http://backend/WeatherForecast");
//var resultContent = await result.Content.ReadAsStringAsync(); //方式二:使用DaprClient
var forecasts = await _daprClient.InvokeMethodAsync<IEnumerable<WeatherForecast>>(HttpMethod.Get, "backend", "weatherforecast");
ViewData["WeatherForecastData"] = forecasts; //方式三:Grpc方式调用
//var forecastsGrpc = await _daprClient.InvokeMethodGrpcAsync<IEnumerable<WeatherForecast>>("backend", "weatherforecast");
//ViewData["WeatherForecastData"] = forecasts;
}
}

  e) 通过Dapr CLI启动DaprFrontEnd,指定sidecar端口为3501,默认为3500,指定app-port是8230,与DaprFrontEnd默认端口保持一致

//命令
dapr run --dapr-http-port 3501 --app-port 8230 --app-id frontend dotnet .\DaprFrontEnd.dll //输出:
Starting Dapr with id frontend. HTTP Port: 3501. gRPC Port: 29840
time="2021-10-24T19:31:25.1254888+08:00" level=info msg="starting Dapr Runtime -- version 1.4.3 -- commit a8ee30180e1183e2a2e4d00c283448af6d73d0d0" app_id=frontend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:31:25.1284879+08:00" level=info msg="log level set to: info" app_id=frontend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:31:25.1294861+08:00" level=info msg="metrics server started on :29841/" app_id=frontend instance=Coder scope=dapr.metrics type=log ver=1.4.3
time="2021-10-24T19:31:25.1458074+08:00" level=info msg="standalone mode configured" app_id=frontend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:31:25.1458074+08:00" level=info msg="app id: frontend" app_id=frontend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:31:25.1463505+08:00" level=info msg="mTLS is disabled. Skipping certificate request and tls validation" app_id=frontend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:31:25.1837081+08:00" level=info msg="local service entry announced: frontend -> 192.168.0.109:29845" app_id=frontend instance=Coder scope=dapr.contrib type=log ver=1.4.3
time="2021-10-24T19:31:25.1837081+08:00" level=info msg="Initialized name resolution to mdns" app_id=frontend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:31:25.184711+08:00" level=info msg="loading components" app_id=frontend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:31:25.2316059+08:00" level=info msg="component loaded. name: pubsub, type: pubsub.redis/v1" app_id=frontend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:31:25.2316059+08:00" level=info msg="waiting for all outstanding components to be processed" app_id=frontend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:31:25.2419333+08:00" level=info msg="component loaded. name: statestore, type: state.redis/v1" app_id=frontend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:31:25.2423401+08:00" level=info msg="all outstanding components processed" app_id=frontend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:31:25.2434172+08:00" level=info msg="enabled gRPC tracing middleware" app_id=frontend instance=Coder scope=dapr.runtime.grpc.api type=log ver=1.4.3
time="2021-10-24T19:31:25.2434172+08:00" level=info msg="enabled gRPC metrics middleware" app_id=frontend instance=Coder scope=dapr.runtime.grpc.api type=log ver=1.4.3
time="2021-10-24T19:31:25.2439954+08:00" level=info msg="API gRPC server is running on port 29840" app_id=frontend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:31:25.2439954+08:00" level=info msg="enabled metrics http middleware" app_id=frontend instance=Coder scope=dapr.runtime.http type=log ver=1.4.3
time="2021-10-24T19:31:25.2445399+08:00" level=info msg="enabled tracing http middleware" app_id=frontend instance=Coder scope=dapr.runtime.http type=log ver=1.4.3
time="2021-10-24T19:31:25.2450858+08:00" level=info msg="http server is running on port 3501" app_id=frontend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:31:25.2450858+08:00" level=info msg="The request body size parameter is: 4" app_id=frontend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:31:25.2456242+08:00" level=info msg="enabled gRPC tracing middleware" app_id=frontend instance=Coder scope=dapr.runtime.grpc.internal type=log ver=1.4.3
time="2021-10-24T19:31:25.2461714+08:00" level=info msg="enabled gRPC metrics middleware" app_id=frontend instance=Coder scope=dapr.runtime.grpc.internal type=log ver=1.4.3
time="2021-10-24T19:31:25.2467123+08:00" level=info msg="internal gRPC server is running on port 29845" app_id=frontend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:31:25.2478066+08:00" level=info msg="application protocol: http. waiting on port 8230. This will block until the app is listening on that port." app_id=frontend instance=Coder scope=dapr.runtime type=log ver=1.4.3
Updating metadata for app command: dotnet .\DaprFrontEnd.dll
You're up and running! Both Dapr and your app logs will appear here. == APP == info: Microsoft.Hosting.Lifetime[0]
== APP == Now listening on: http://0.0.0.0:8230
== APP == info: Microsoft.Hosting.Lifetime[0]
== APP == Application started. Press Ctrl+C to shut down.
== APP == info: Microsoft.Hosting.Lifetime[0]
== APP == Hosting environment: Production
== APP == info: Microsoft.Hosting.Lifetime[0]
== APP == Content root path: F:\coding\DaprMultiContainer\DaprFrontEnd\bin\Debug\netcoreapp3.1
time="2021-10-24T19:31:26.10297+08:00" level=info msg="application discovered on port 8230" app_id=frontend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:31:26.2373056+08:00" level=info msg="application configuration loaded" app_id=frontend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:31:26.2422307+08:00" level=info msg="actor runtime started. actor idle timeout: 1h0m0s. actor scan interval: 30s" app_id=frontend instance=Coder scope=dapr.runtime.actor type=log ver=1.4.3
time="2021-10-24T19:31:26.2677804+08:00" level=info msg="dapr initialized. Status: Running. Init Elapsed 1121.4194ms" app_id=frontend instance=Coder scope=dapr.runtime type=log ver=1.4.3
time="2021-10-24T19:31:26.5035983+08:00" level=info msg="placement tables updated, version: 0" app_id=frontend instance=Coder scope=dapr.runtime.actor.internal.placement type=log ver=1.4.3

  查看dapr运行应用情况:

dapr list
APP ID HTTP PORT GRPC PORT APP PORT COMMAND AGE CREATED PID
backend 3511 1030 5000 dotnet .\DaprBack... 32m 2021-10-24 19:00.47 4900
frontend 3501 29840 8230 dotnet .\DaprFron... 1m 2021-10-24 19:31.24 20856

 4、dapr cli 调用方式:

dapr invoke --app-id backend --verb "GET" --method weatherforecast

三、Dapr扩展功能:

 1、链路跟踪查看:自承载的方式下,Dapr默认启动了zipkin容器,可以通过以下链接查看: http://localhost:9411/zipkin/

  

 2、Dapr Dashboard:

  a) 启动 Dapr Dashboard:

dapr dashboard

  b) 查看页面:http://localhost:8080/

  

总结:

 本篇对构建块中服务调用进行了解,并在.NET Core 程序中进行了验证。   

Dapr-服务调用的更多相关文章

  1. YARP实现Dapr服务调用的反向代理

    楔子 公司即将新开项目,打算用点时髦的技术,需要探探路.之前没做过微服务项目,没有技术栈方面的积(负)累(债), 干脆就上微软的分布式运行时Dapr......嗯......用来服务发现,然后等测试用 ...

  2. Dapr初体验之服务调用

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

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

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

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

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

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

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

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

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

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

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

  8. Caller 服务调用 - Dapr

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

  9. 3. Caller 服务调用 - dapr

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

  10. 让服务调用更简单 - Caller.HttpClient

    前言 绝大多数项目都离不开服务调用,服务的调用方式通常是基于Http.RPC协议的调用,需要获取到对应服务的域名或者ip地址以及详细的控制器方法后才能进行调用,如果项目需要支持分布式部署,则需要借助服 ...

随机推荐

  1. uniapp 封装 request 并 配置跨域,( 本地 + 线上 + 封装 )

    找到上面这个 文件,不管是用 命令创建 还是 用 HBX 创建,都一样会有这个文件的,然后跟着截图复制粘贴就好了. // 这是配置本地能跨域的,或者你可以直接让后端给你设置请求头,避免了跨域. &qu ...

  2. 【曹工杂谈】Maven和Tomcat能有啥联系呢,都穿打补丁的衣服吗

    Maven和Tomcat能有啥联系呢,都穿打补丁的衣服吗 前奏 我们上篇文章,跟大家说了下,怎么调试maven插件的代码,注意,是插件的代码.插件,是要让主框架来执行的,主框架是谁呢,就是maven ...

  3. 2021秋 noip 模拟赛

    9.9 T3 第负二题 \(f_i\) 的数学意义:中心在第 \(i\) 行的全 \(1\) 组成的最大正方形(对角线水平/竖直),对角线长 \(2f_i-1\). 显然 \(f_i\) 具有单调性( ...

  4. Smooth

      考场\(AC\),还是很开心的.   考虑这题让你干啥,就是给你一堆素数,然后让你用他们去构造数,求其中第\(k\)小的.   我们可以用系数累乘的方式,同时利用小根堆实现有序,加一个优化,就过了 ...

  5. 代码注释规范之Doxygen

    1.Doxygen简介 Doxygen是一个程序的文档产生工具,可以将程序中的注释转换成说明文档或者说是API参考手册,从而减少程序员整理文档的时间.当然这里程序中的注释需要遵循一定的规则书写,才能让 ...

  6. (三、四)Superset 1.3图表篇——透视表-Pivot Table

    本系列文章基于Superset 1.3.0版本.1.3.0版本目前支持分布,趋势,地理等等类型共59张图表.本次1.3版本的更新图表有了一些新的变化,而之前也一直没有做过非常细致的图表教程. 而且目前 ...

  7. Weblogic Coherence组件漏洞初探CVE-2020-2555

    Weblogic Coherence组件漏洞初探CVE-2020-2555 2020年1月,互联网上爆出了weblogic反序列化远程命令执行漏洞(CVE-2020-2555),Oracle Fusi ...

  8. vs2015使用tcmalloc(windows)

    编译lib库 1.https://github.com/gperftools/gperftools  去tag中下载了2.4版本(最新的2.9.1版本 用了c++17的新特性折叠表达式,vs2015不 ...

  9. 【转】Linux 查看端口占用情况

    Linux 查看端口占用情况可以使用 lsof 和 netstat 命令. lsof lsof(list open files)是一个列出当前系统打开文件的工具. lsof 查看端口占用语法格式: l ...

  10. 使用git克隆仓库到本地报错:SSL certificate problem: unable to get local issuer certificate

    第一次使用Git工具克隆仓库,使用的是HTTPS链接,失败了.发现是因为通过HTTPS访问时,如果服务器上的SSL证书未经过第三方机构认证,Git就会报错. 解决方法:通过命令关闭验证 git con ...