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 提供两个服务

  • 获取所有产品集合

  • 添加产品

  1. 使用 ASP.Net Core 创建 ProductService ,具体参考源码

  2. Dapr 启动 ProductService

    dapr run --app-id productService --app-port 5000 dotnet run
  3. 获取所有产品集合,使用 curl 命令

    curl -X GET http://localhost:5000/getlist

    或者

    curl -X GET http://localhost:54680/v1.0/invoke/productService/method/getlist
  4. 添加一个产品

    curl -X POST https://localhost:5001/product -H "Content-Type: application/json" -d "{ \"id\": \"14a3611d-1561-455f-9c72-381eed2f6ee3\" }"
  5. 重点,通过 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

  1. 创建 Server

    package mainimport ("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 listinerlis, err := net.Listen("tcp", ":4000")if err != nil {log.Fatalf("failed to listen: %v", err)}// create grpc servers := 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 stringfmt.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
    }
    
  2. 使用 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

  1. 使用 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 Clientstring 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 。

    源码地址:https://github.com/SoMeDay-Zhang/DaprDemos

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

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

相关文章

微软将中止支持 .NET Core 2.2,建议开发者升级至 .NET Core 3.1

Current 版本 .NET Core 2.2 将在 12 月 23 日结束生命周期&#xff0c;开发者应更新到长期支持版本 .NET Core 3.1。.NET Core 2.2 于 2018 年 12 月 4 日发布&#xff0c;作为一个非 LTS 版本(“Current”)&#xff0c;它只在下一个版本发布后的三个月内受支持。.NET Core 3.…

LeetCode贪心 数组拆分I

Given an integer array nums of 2n integers, group these integers into n pairs (a1, b1), (a2, b2), …, (an, bn) such that the sum of min(ai, bi) for all i is maximized. Return the maximized sum. 思路 这道题要使得各最小值相加最小&#xff0c;就要使得的每一组…

使用.NET Core创建Windows服务 - 使用.NET Core工作器方式

原文&#xff1a;Creating Windows Services In .NET Core – Part 3 – The “.NET Core Worker” Way作者&#xff1a;Dotnet Core Tutorials译者&#xff1a;Lamond Lu译文&#xff1a;使用.NET Core创建Windows服务 - 使用.NET Core工作器方式使用.NET Core创建Windows服务…

LeetCode贪心 最长回文串

Given a string s which consists of lowercase or uppercase letters, return the length of the longest palindrome that can be built with those letters. Letters are case sensitive, for example, “Aa” is not considered a palindrome here. 思路 首先学习一个新单…

【译】Visual Studio 2019 中 WPF UWP 的 XAML 开发工具新特性

原文 | Dmitry翻译 | 郑子铭自Visual Studio 2019推出以来&#xff0c;我们为使用WPF或UWP桌面应用程序的XAML开发人员发布了许多新功能。在本周的 Visual Studio 2019 版本 16.4 和 16.5 Preview 1中&#xff0c;我们希望借此机会回顾一下全年的新变化。如果您错过了我们以前的…

numpy创建zeros数组时报错TypeError: Cannot interpret ‘8‘ as a data type

错误代码 xPoint np.zeros(pow(2, k), pow(2, k))改正方法 zeros括号内填数组行列数时&#xff0c;加一对括号。 正确代码 xPoint np.zeros((pow(2, k), pow(2, k)))

我在外包公司做增删改查有前途么?

作者&#xff1a;邹溪源&#xff0c;长沙资深互联网从业者&#xff0c;架构师社区特邀嘉宾&#xff01;起因这是我无意中在筛选简历时&#xff0c;看到一位朋友发布的求职说明中&#xff0c;明确指出&#xff0c;外包勿扰&#xff0c;并给出了他做出这个决定的理由&#xff1a;…

csv.reader读取txt中的文本数据

Python里读取txt文件的方法有很多&#xff0c;但numpy读取字符串比较困难&#xff0c;这时可以考虑使用csv库&#xff0c;读取txt文件中的每一行文本。 代码 data [] with open(*******.txt, rt) as csvfile:reader csv.reader(csvfile, delimiter,)for row in reader:data…

[译]C#8.0中一个使接口更加灵活的新特性-默认接口实现

9月份的时候&#xff0c;微软宣布正式发布C#8.0&#xff0c;作为.NET Core 3.0发行版的一部分。C#8.0的新特性之一就是默认接口实现。在本文中&#xff0c;我们将一起来聊聊默认接口实现。众所周知&#xff0c;对现有应用程序的接口进行更改是一项很危险的操作。如果这个接口又…

Linux服务器 常用命令

定义当前文件夹中有result.txt 查看当前文件夹ls 查看当前路径pwd 进入目录homecd home 返回上一级目标cd .. 查看文件内容less result.txt 删除文件rm result.txt 查看进程信息top

鲲鹏来了,在EulerOS试用.NETCore-3.1

在EulerOS试用.NETCore-3.1前言EulerOS其实出来有一段时间了&#xff0c;一直在关注&#xff0c;单是仅仅也只是停留在观望的阶段&#xff0c;目前还没有接入的打算&#xff1b;正好看到园子里的兄弟分享了华为云免费试用的活动后&#xff0c;难捺激动的心情&#xff0c;我马上…

scp连接计算节点操作

定义计算节点为ip&#xff0c;计算节点用户名为name&#xff0c;待运行的文件名为file&#xff0c;其在登录节点的路径为path&#xff0c;登录节点文件夹名为log 登录计算节点 ssh nameip将登录节点的文件传输到计算节点 scp -r file nameip:path反之&#xff0c;将计算节点…

如何在ASP.NET Core 中快速构建PDF文档

比如我们需要ASP.NET Core 中需要通过PDF来进行某些简单的报表开发&#xff0c;随着这并不难&#xff0c;但还是会手忙脚乱的去搜索一些资料&#xff0c;那么恭喜您&#xff0c;这篇帖子会帮助到您&#xff0c;我们就不会再去浪费一些宝贵的时间。在本文中我们将要使用DinkToPD…

动态规划 0-1背包问题 二维数组

定义 dp[i][j]是从物品0到i中挑选物品&#xff0c;放进容量为j的背包中的最大价值总和。 初始化 int dp[maxn][maxn]; memset(dp, sizeof(dp), -0x3f3f3f3f);for(int j bag_size; j > 0; j--) dp[0][j] dp[0][j-weight[0]] values[0];先遍历物品法 for(int i 0; i &l…

在VS2019发布独立程序与单一执行程序

背景随着.NET Core 3.1 LTS的发布&#xff0c;.NET Core 3.1 进入了3年的支持周期&#xff0c;在这期间使用.NET 的人数肯定会发生一个质的飞跃。01目标本次主要集中在使用.NET Core 3.1 WPF程序发布一个独立的单一执行程序。首先&#xff0c;新建一个wpf项目&#xff0c;名称为…

动态规划 0-1背包问题 滚动数组

定义 dp[j]是从物品0到i中挑选物品&#xff0c;放进容量为j的背包中的最大价值总和。 初始化 int dp[maxn]; memset(dp, sizeof(dp), -0x3f3f3f3f);一维滚动数组法 for(int i 0; i < weight.size(); i)for(int j bag_size; j > 0; j--){if(j < weight[i])dp[j] …

C#异步编程看这篇就够了

随着.NET Core的流行&#xff0c;相信你现在的代码中或多或少的会用到async以及await吧&#xff01;毕竟已成标配。那么我们为什么要用async以及await呢&#xff1f;其实这是微软团队为我们提供的一个语法糖&#xff0c;让我们不用996就可以轻松的编写异步代码&#xff0c;并无…

sklearn PCA特征降维

机器学习中降维能够消除冗余&#xff0c;防止过拟合&#xff1b;发现潜在特征&#xff1b;减小计算量&#xff0c;节省资源和时间&#xff0c;常用的降维方法有&#xff1a;PCA &#xff0c;ICA&#xff0c;SOM&#xff0c;MDS&#xff0c; ISOMAP&#xff0c;LLE&#xff0c;本…

2019 AI Bootcamp·Guangzhou 参会日记

2019年的全球AI训练营在北京、上海、广州、杭州、宁波五个地方同时举办&#xff01;12月14日&#xff0c;微软全球AI Bootcamp活动再次驾临广州&#xff0c;本次会议结合 ML.NET 和基于 SciSharp 社区介绍最新的基于 .NET Core 人工智能技术&#xff0c;还有云端人工智能解决方…

LeetCode动态规划 杨辉三角

Given an integer numRows, return the first numRows of Pascal’s triangle. In Pascal’s triangle, each number is the sum of the two numbers directly above it as shown: 前几天做的动态规划题好难呜呜&#xff0c;做道水题找回自信~ 状态转移方程 triangle[i][j] …