Dapr 运用
Dapr 运用
- 前置条件
- Docker
- Win10
Dapr 部署
本文将采用本地部署的方式。
安装 Dapr CLI
打开 Windows PowerShell 或 cmd ,运行以下命令以安装 Dapr CLI,并添加安装路径到系统环境变量中。
powershell -Command "iwr -useb https://raw.githubusercontent.com/dapr/cli/master/install/install.ps1 | iex"
这里安装可能会失败。如果失败可以手动安装。
- 打开 Dapr 发布页面下载
dapr_windows_amd64.zip - 解压文件 zip 文件
- 把解压后的文件拷贝到
C:\dapr中
安装 MySql
Docker 启动 Mysql
docker run --name mysqltest -e MYSQL_ROOT_PASSWORD=123456 -d mysql
使用 Dapr CLI 安装 Darp runtime
在 Windows PowerShell 或 cmd 中使用命令 dapr init 以安装 Dapr。

同时可以在 Docker 中查看 Dapr 容器。

至此,一个本地 Dapr 服务搭建完成。
使用 Asp.Net Core 搭建 ProductService 服务
ProductService 提供两个服务
- 获取所有产品集合
- 添加产品
使用
ASP.Net Core创建 ProductService ,具体参考源码Dapr 启动 ProductService
dapr run --app-id productService --app-port 5000 dotnet run
获取所有产品集合,使用 curl 命令
curl -X GET http://localhost:5000/getlist
或者
curl -X GET http://localhost:54680/v1.0/invoke/productService/method/getlist
添加一个产品
curl -X POST https://localhost:5001/product -H "Content-Type: application/json" -d "{ \"id\": \"14a3611d-1561-455f-9c72-381eed2f6ee3\" }"
重点,通过 Dapr 添加一个产品,先看添加产品的代码
/// <summary>
/// 创建产品
/// </summary>
/// <param name="productCreate">产品创建模型</param>
/// <returns></returns>
[Topic("product")]
[HttpPost("product")]
public async Task<bool> CreateProduct(ProductCreate productCreate)
{
_productContext.Products.Add(new Product
{
ProductID = productCreate.ID
});
return await _productContext.SaveChangesAsync() == 1;
}
使用 Dapr cli 发布事件
dapr invoke -a productService -m product -p "{\"id\":\"b1ccf14a-408a-428e-b0f0-06b97cbe4135\"}"
输出为:
true
App invoked successfully
使用 curl 命令直接请求 ProductService 地址
curl -X POST http://localhost:5000/product -H "Content-Type: application/json" -d "{ \"id\": \"14a3611d-1561-455f-9c72-381eed2f64e3\" }"
输出为:
true
使用 curl 命令通过 Dapr runtime
curl -X POST http://localhost:54680/v1.0/invoke/productService/method/product -H "Content-Type: application/json" -d "{ \"id\": \"14a3611d-1561-455f-9c72-381eed2f54e3\" }"
输出为:
true
注意:
- Dapr 使用 App 端口号应与服务端口号相同,例如:
ASP.Net Core服务端口号为5000,则在使用 Dapr 托管应用程序时的端口号也应使用 5000
至此, ProductService 创建完成。
使用 Golang 创建 gRPC Server
创建 Server
package main import (
"context"
"fmt"
"log"
"net" "github.com/golang/protobuf/ptypes/any"
"github.com/golang/protobuf/ptypes/empty" pb "github.com/dapr/go-sdk/daprclient"
"google.golang.org/grpc"
) // server is our user app
type server struct {
} func main() {
// create listiner
lis, err := net.Listen("tcp", ":4000")
if err != nil {
log.Fatalf("failed to listen: %v", err)
} // create grpc server
s := grpc.NewServer()
pb.RegisterDaprClientServer(s, &server{}) fmt.Println("Client starting...") // and start...
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
} // Sample method to invoke
func (s *server) MyMethod() string {
return "Hi there!"
} // This method gets invoked when a remote service has called the app through Dapr
// The payload carries a Method to identify the method, a set of metadata properties and an optional payload
func (s *server) OnInvoke(ctx context.Context, in *pb.InvokeEnvelope) (*any.Any, error) {
var response string fmt.Println(fmt.Sprintf("Got invoked with: %s", string(in.Data.Value))) switch in.Method {
case "MyMethod":
response = s.MyMethod()
}
return &any.Any{
Value: []byte(response),
}, nil
} // Dapr will call this method to get the list of topics the app wants to subscribe to. In this example, we are telling Dapr
// To subscribe to a topic named TopicA
func (s *server) GetTopicSubscriptions(ctx context.Context, in *empty.Empty) (*pb.GetTopicSubscriptionsEnvelope, error) {
return &pb.GetTopicSubscriptionsEnvelope{
Topics: []string{"TopicA"},
}, nil
} // Dapper will call this method to get the list of bindings the app will get invoked by. In this example, we are telling Dapr
// To invoke our app with a binding named storage
func (s *server) GetBindingsSubscriptions(ctx context.Context, in *empty.Empty) (*pb.GetBindingsSubscriptionsEnvelope, error) {
return &pb.GetBindingsSubscriptionsEnvelope{
Bindings: []string{"storage"},
}, nil
} // This method gets invoked every time a new event is fired from a registerd binding. The message carries the binding name, a payload and optional metadata
func (s *server) OnBindingEvent(ctx context.Context, in *pb.BindingEventEnvelope) (*pb.BindingResponseEnvelope, error) {
fmt.Println("Invoked from binding")
return &pb.BindingResponseEnvelope{}, nil
} // This method is fired whenever a message has been published to a topic that has been subscribed. Dapr sends published messages in a CloudEvents 0.3 envelope.
func (s *server) OnTopicEvent(ctx context.Context, in *pb.CloudEventEnvelope) (*empty.Empty, error) {
fmt.Println("Topic message arrived")
return &empty.Empty{}, nil
}使用 Dapr 命令启动 StorageService
dapr run --app-id client --protocol grpc --app-port 4000 go run main.go
注意:
- Dapr 使用 App 端口号应与服务端口号相同,使用 --protocal grpc 指定通讯协议为 grpc 。此外,OnInvoke 中的 switch 方法用于调用者路由。
使用 ASP.NET Core 创建 StorageService
使用 NuGet 获取程序管理包控制台安装以下包
- Dapr.AspNetCore
- Dapr.Client.Grpc
- Grpc.AspNetCore
- Grpc.Net.Client
- Grpc.Tools
Startup.cs文件中修改代码如下:/// <summary>
/// This method gets called by the runtime. Use this method to add services to the container.
/// </summary>
/// <param name="services">Services.</param>
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers().AddDapr();
services.AddDbContextPool<StorageContext>(options => { options.UseMySql(Configuration.GetConnectionString("MysqlConnection")); });
}
/// <summary>
/// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
/// </summary>
/// <param name="app">app.</param>
/// <param name="env">env.</param>
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} app.UseRouting();
app.UseCloudEvents(); app.UseAuthorization(); app.UseEndpoints(endpoints =>
{
endpoints.MapSubscribeHandler();
endpoints.MapControllers();
});
}
添加
StorageController.cs文件,内容如下using System;
using System.Linq;
using System.Threading.Tasks;
using Dapr.Client.Grpc;
using Google.Protobuf;
using Grpc.Net.Client;
using Microsoft.AspNetCore.Mvc;
using StorageService.Api.Entities; namespace StorageService.Api.Controllers
{
[ApiController]
public class StorageController : ControllerBase
{
private readonly StorageContext _storageContext; public StorageController(StorageContext storageContext)
{
_storageContext = storageContext;
} /// <summary>
/// 初始化仓库.
/// </summary>
/// <returns>是否成功.</returns>
[HttpGet("InitialStorage")]
public async Task<bool> InitialStorage()
{
string defaultPort = Environment.GetEnvironmentVariable("DAPR_GRPC_PORT") ?? "54681"; // Set correct switch to make insecure gRPC service calls. This switch must be set before creating the GrpcChannel.
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); // Create Client
string daprUri = $"http://127.0.0.1:{defaultPort}";
GrpcChannel channel = GrpcChannel.ForAddress(daprUri);
var client = new Dapr.Client.Grpc.Dapr.DaprClient(channel);
Console.WriteLine(daprUri); InvokeServiceResponseEnvelope result = await client.InvokeServiceAsync(new InvokeServiceEnvelope
{
Method = "MyMethod",
Id = "client",
Data = new Google.Protobuf.WellKnownTypes.Any
{
Value = ByteString.CopyFromUtf8("Hello ProductService")
}
});
Console.WriteLine("this is call result:" + result.Data.Value.ToStringUtf8());
//var productResult = result.Data.Unpack<ProductList.V1.ProductList>();
//Console.WriteLine("this is call result:" + productResult.Results.FirstOrDefault());
return true;
} /// <summary>
/// 修改库存
/// </summary>
/// <param name="storage"></param>
/// <returns></returns>
[HttpPut("Reduce")]
public bool Reduce(Storage storage)
{
Storage storageFromDb = _storageContext.Storage.FirstOrDefault(q => q.ProductID.Equals(storage.ProductID));
if (storageFromDb == null)
{
return false;
} if (storageFromDb.Amount <= storage.Amount)
{
return false;
} storageFromDb.Amount -= storage.Amount;
return true;
}
}
}
使用 Dapr cli 启用 StorageService 服务
dapr run --app-id storageService --app-port 5003 dotnet run
使用 curl 命令访问 StorageService InitialStorage 方法
curl -X GET http://localhost:56349/v1.0/invoke/storageService/method/InitialStorage
输入
true
其中打印信息为:
this is call result:Hi there!
注意:
- Dapr 使用 App 端口号应与服务端口号相同,例如:
ASP.Net Core服务端口号为5003,则在使用 Dapr 托管应用程序时的端口号也应使用 5003,在 Client.InvokeServiceAsync 中的 Id 指被调用方的 App-Id ,Method 指被调用方方法名称。参考 Go Server 中 OnInvoke 方法的 Switch 。
Dapr 运用的更多相关文章
- 技术分享:Dapr,让开发人员更轻松地构建微服务应用
最近一直在学习微服务相关的技术.微服务架构已成为构建云原生应用程序的标准,并且可以预见,到2022年,将有90%的新应用程序采用微服务架构.微服务架构提供了令人信服的好处,包括可伸缩性,松散的服务耦合 ...
- 微软的分布式应用框架 Dapr Helloworld
Dapr HelloWorld Dapr Distributed Application Runtime. An event-driven, portable runtime for building ...
- 微软的分布式应用框架 Dapr
微服务架构已成为构建云原生应用程序的标准,微服务架构提供了令人信服的好处,包括可伸缩性,松散的服务耦合和独立部署,但是这种方法的成本很高,需要了解和熟练掌握分布式系统.为了使用所有开发人员能够使用任何 ...
- dapr微服务.netcore sdk入门
Actors入门 先决条件 .Net Core SDK 3.0 Dapr CLI Dapr DotNet SDK 概述 本文档描述如何在客户端应用程序上创建Actor(MyActor)并调用其方法. ...
- Dapr 运用之 Java gRPC 调用篇
JAVA GRPC 服务与调用 安装协议编译器 下载对应的版本编译器,并把路径加入到环境变量中,执行以下命令生成代码 protoc -I=$SRC_DIR --java_out=$DST_DIR $S ...
- Dapr 运用之集成 Asp.Net Core Grpc 调用篇
前置条件: <Dapr 运用> 改造 ProductService 以提供 gRPC 服务 从 NuGet 或程序包管理控制台安装 gRPC 服务必须的包 Grpc.AspNetCore ...
- .NetCore集成Dapr踩坑经历
该篇内容由个人博客点击跳转同步更新!转载请注明出处 前言 之前自己有个core2.2的项目一直是用的Surging作为微服务框架的,后来了解到了Dapr,发现比较轻量级,开发部署等也非常方便,故将自己 ...
- Dapr Pub/Sub 集成 RabbitMQ 、Golang、Java、DotNet Core
前置条件: <Dapr运用> <Dapr 运用之 Java gRPC 调用篇> <Dapr 运用之集成 Asp.Net Core Grpc 调用篇> 搭建 Rabb ...
- Dapr实现分布式有状态服务的细节
Dapr是为云上环境设计的跨语言, 事件驱动, 可以便捷的构建微服务的系统. balabala一堆, 有兴趣的小伙伴可以去了解一下. Dapr提供有状态和无状态的微服务. 大部分人都是做无状态服务(微 ...
随机推荐
- Vim 便捷 | 自己的Vim
在.vimrc中安排自己的Vim set softtabstop=4 "将连续数量的空格视为一个制表符 set shiftwidth=4 "自动缩进所使用的空白数 set auto ...
- wifi各协议最高速率
- MySQL InnoDB MVCC
MySQL 原理篇 MySQL 索引机制 MySQL 体系结构及存储引擎 MySQL 语句执行过程详解 MySQL 执行计划详解 MySQL InnoDB 缓冲池 MySQL InnoDB 事务 My ...
- 解决vue低版本安卓手机兼容性问题
低版本的安卓手机可能会白屏,是由新特性不支持引起的 解决代码es6新特性兼容问题 1,npm 安装 npm install babel-polyfill npm install es6-promise ...
- nyoj 33-蛇形填数 (循环,模拟)
33-蛇形填数 内存限制:64MB 时间限制:3000ms Special Judge: No accepted:15 submit:38 题目描述: 在n*n方陈里填入1,2,...,n*n,要求填 ...
- Test Complete 的自动化测试 --- 三角形
Test Complete 的自动化测试 --- 三角形 PS:工具:Test Complete , OS:win 10 这里做三角形的测试与上一篇博客做计算器的测试大致一样,都是对.exe的执行文件 ...
- 基于 cobbler 实现自动安装 linux 系统
使用 cobbler 实现自动安装 centos 6.7系统 1.yum install cobbler -y 安装 cobbler ,有依赖关系,会自动把 TFTP .HTTP 服务安装上:cobb ...
- 理解Redis的反应堆模式
1. Redis的网络模型 Redis基于Reactor模式(反应堆模式)开发了自己的网络模型,形成了一个完备的基于IO复用的事件驱动服务器,但是不由得浮现几个问题: 为什么要使用Reactor模式呢 ...
- Install python3
wget https://www.python.org/ftp/python/3.7.4/Python-3.7.4.tgz tar xf Python-3.7.4.tgz cd Python-3.7. ...
- STDN: Scale-Transferrable Object Detection论文总结
概述 STDN是收录于CVPR 2018的一篇目标检测论文,提出STDN网络用于提升多尺度目标的检测效果.要点包括:(1)使用DenseNet-169作为基础网络提取特征:(2)提出Scale-tra ...