当前位置:网站首页>3. Caller 服务调用 - dapr
3. Caller 服务调用 - dapr
2022-06-28 15:34:00 【InfoQ】
前言
Caller.Dapr 入门
- 改造Caller 服务调用 - HttpClient的中的服务端,使得服务端支持dapr调用
- 调整客户端代码,使客户端支持通过dapr来做到服务调用,并达到与HttpClient调用相同的结果
准备工作
- 安装.Net 6.0
- 创建ASP.NET Core 空白解决方案
Assignment03
- 将
Assignment02文件夹下的Assignment.Server复制到Assignment03的文件夹下,然后将项目Assignment.Server添加到解决方案Assignment03中
- 选中
Assignment.Server并安装Masa.Utils.Development.Dapr.AspNetCore
dotnet add package Masa.Utils.Development.Dapr.AspNetCore --version 0.4.0-rc1- 修改
Assignment.Server项目下的Program.cs
//忽略命名空间引用
var builder = WebApplication.CreateBuilder(args);
// 添加DaprStarter,用于服务端启动dapr sidecar,改造服务端支持dapr调用的重点(建议在开发环境下使用,线上环境使用k8s部署)
builder.Services.AddDaprStarter(option =>
{
option.AppId = "Assignment-Server";
option.DaprGrpcPort = 7007;
option.DaprHttpPort = 7008;
option.AppIdSuffix = string.Empty;
});
var app = builder.Build();
/// 忽略路由等
- 创建ASP.NET Core 空项目
Assignment.Client.DaprClientWeb作为客户端并安装Masa.Utils.Caller.DaprClient
dotnet add package Masa.Utils.Caller.DaprClient --version 0.4.0-rc1- 修改
Assignment.Client.DaprClientWeb项目下的Program.cs
using Masa.Utils.Caller.Core;
using Masa.Utils.Caller.DaprClient;
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCaller(option =>
{
// 注意: 与Caller.HttpClient相比,需要修改的地方
options.UseDapr(masaDaprClientBuilder =>
{
masaDaprClientBuilder.Name = "userCaller"; // 当前Caller的别名(仅有一个Caller时可以不填),Name不能重复
masaDaprClientBuilder.IsDefault = true; // 默认的Caller支持注入ICallerProvider获取(仅有一个Caller时可不赋值)
masaDaprClientBuilder.AppId = "Assignment-Server";//设置当前caller下Dapr的AppId
});
});
var app = builder.Build();
app.MapGet("/", () => "Hello HttpClientWeb.V1!");
app.MapGet("/Test/User/Get", async ([FromServices] ICallerProvider callerProvider) =>
{
var user = await callerProvider.GetAsync<object, UserDto>("User", new { id = new Random().Next(1, 10) });
return $"获取用户信息成功:用户名称为:{user!.Name}";
});
app.MapGet("/Test/User/Add", async ([FromServices] ICallerProvider callerProvider) =>
{
var dateTimeOffset = new DateTimeOffset(DateTime.UtcNow);
string timeSpan = dateTimeOffset.ToUnixTimeSeconds().ToString();
var userName = "ss_" + timeSpan; //模拟一个用户名
string? response = await callerProvider.PostAsync<object, string>("User", new { Name = userName });
return $"创建用户成功了,用户名称为:{response}";
});
app.Run();
public class UserDto
{
public int Id { get; set; }
public string Name { get; set; } = default!;
}
Assignment.Client.HttpClientWebAssignment.Client.DaprClientWebProgram.csUseHttpClientUseDapr- 添加环境变量
DAPR_GRPC_PORT,值为7007、DAPR_HTTP_PORT,值为7008
- Q: 为什么要添加环境变量? A: 由于当前客户端并未使用dapr sidecar,若当前客户端也使用dapr sidecar,此处可以不添加环境变量
Assignment.ServerAssignment.Client.DaprClientWebhttp://localhost:5042/Test/User/Gethttp://localhost:5042/Test/User/Add

DaprClient 最佳实践
Assignment.Client.DaprClientWebAssignment.Client.HttpClientWeb- 创建ASP.NET Core 空项目
Assignment.Client.DaprClientWeb.V2作为调用方V2版本
- 选中
Assignment.Client.DaprClientWeb.V2并安装Masa.Utils.Caller.DaprClient
dotnet add package Masa.Utils.Caller.DaprClient --version 0.4.0-rc1- 添加类
ServerCallerBase(对应服务端服务)
using Masa.Utils.Caller.DaprClient;
namespace Assignment.Client.DaprClientWeb.V2;
/// <summary>
/// 注意:ServerCallerBase是抽象类哟(抽象类不会被DI注册), 与使用Caller.HttpClient相比,需要修改的是继承的基类改为DaprCallerBase
/// </summary>
public abstract class ServerCallerBase : DaprCallerBase
{
protected override string AppId { get; set; } = "Assignment-Server";//设置当前Caller需要请求的服务端项目Dapr的AppId
public ServerCallerBase(IServiceProvider serviceProvider) : base(serviceProvider)
{
}
}
- 添加类
UserCaller.cs
namespace Assignment.Client.DaprClientWeb.V2;
public class UserCaller : ServerCallerBase
{
public UserCaller(IServiceProvider serviceProvider) : base(serviceProvider)
{
}
/// <summary>
/// 调用服务获取用户信息
/// </summary>
/// <param name="id">用户id</param>
/// <returns></returns>
public Task<UserDto?> GetUserAsync(int id)
=> CallerProvider.GetAsync<object, UserDto>("User", new { id = id });
/// <summary>
/// 调用服务添加用户
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public Task<string?> AddUserAsync(string userName)
=> CallerProvider.PostAsync<object, string>("User", new { Name = userName });
}
public class UserDto
{
public int Id { get; set; }
public string Name { get; set; } = default!;
}
- 添加环境变量
DAPR_GRPC_PORT,值为7007、DAPR_HTTP_PORT,值为7008
Assignment.ServerAssignment.Client.DaprClientWeb.V2http://localhost:5102/Test/User/Gethttp://localhost:5102/Test/User/Add

常见问题
- 一个项目在同一个k8s集群部署了两套环境,为什么会出现代码调用混乱(开发环境调用线上环境)?
在于同一个K8s集群下,dapr会将服务组网,并将它们认为是同一个服务(AppId一致的服务)。- 如何解决同一个k8s集群中调用混乱的问题?
解决方案有两种:
1. 将不同环境下的服务分别部署在不同的K8s集群
2. 根据环境调整相对应服务的dapr sidecar的配置,其`AppId`的命名规则:`AppId`-`环境名`。修改自定义Caller的规则:
public abstract class CustomizeDaprCallerBase : DaprCallerBase
{
protected CustomizeDaprCallerBase(IServiceProvider serviceProvider) : base(serviceProvider)
{
var hostEnvironment = serviceProvider.GetRequiredService<IWebHostEnvironment>();
if (!hostEnvironment.IsDevelopment() || hostEnvironment.IsStaging())
AppId = AppId + "-" + hostEnvironment.EnvironmentName;
}
}
- 如何修改支持自定义Header?
目前Caller.Dapr不支持自定义Header,目前只能使用`SendAsync`才能自定义Header,不过此功能已经在0.5.0的开发计划中,在0.5.0中会支持总结
Caller.HttpClientCaller.Dapr本章源码
开源地址

边栏推荐
- The Web3.0 era is coming. See how Tianyi cloud storage resources invigorate the system to enable new infrastructure (Part 1)
- Grand launch of qodana: your favorite CI code quality platform
- 分布式 CAP 定理的前世今生
- Notes to distributed theory
- ROS knowledge points - build an ROS development environment using vscode
- Jenkins的安装及使用
- MIPS assembly language learning-03-cycle
- R language ggplot2 visualization: use the patchwork package (directly use the plus sign +) to horizontally combine a ggplot2 visualization result and a piece of text content to form a final result gra
- Openharmony - detailed source code of Kernel Object Events
- Validate palindrome string
猜你喜欢

GBASE南大通用亮相第六届世界智能大会

Fleet |「后台探秘」第 3 期:状态管理

Web3.0时代来了,看天翼云存储资源盘活系统如何赋能新基建(上)

Grand launch of qodana: your favorite CI code quality platform
Oracle11g database uses expdp to back up data every week and upload it to the backup server

MongoDB 在腾讯零售优码中的应用

Qt5.5.1 configuring msvc2010 compiler and WinDbg debugger

Talking about open source - Linus and Jim talk about open source in China

What useful supplier management systems are available

如何从零搭建10万级 QPS 大流量、高并发优惠券系统
随机推荐
The k-th element in the array [heap row + actual time complexity of heap building]
经典模型——Transformer
DBMS in Oracle_ output. put_ Line output problem solving process
REDIS00_详解redis.conf配置文件
Yiwen teaches you to quickly generate MySQL database diagram
Spark SQL generate JSON
Complete model training routine (I)
Analysis of PostgreSQL storage structure
一个bug肝一周...忍不住提了issue
R语言ggplot2可视化:使用patchwork包(直接使用加号+)将一个ggplot2可视化结果和数据表格横向组合起来形成最终结果图
SaaS application management platform solution in the education industry: help enterprises realize the integration of operation and management
Cross cluster deployment of helm applications using karmada
R language ggplot2 visualization: use the patchwork package (directly use the plus sign +) to horizontally combine a ggplot2 visualization result and a data table to form a final result graph
Qt5.5.1配置MSVC2010编绎器和windbg调试器
【高并发基础】MySQL 不同事务隔离级别下的并发隐患及解决方案
The best time to buy and sell stocks
R语言ggplot2可视化:patchwork包将一个ggplot2可视化结果和一个plot函数可视化结果横向组合起来形成最终结果图、两个可视化的组合结果对齐、并为组合图像的每个子图添加标题
Not being a meta universe now is like not buying a house 20 years ago!
隐私计算 FATE - 离线预测
Leetcode 48. Rotate image (yes, resolved)