分布式应用框架 Dapr

微服务架构已成为构建云原生应用程序的标准,微服务架构提供了令人信服的好处,包括可伸缩性,松散的服务耦合和独立部署,但是这种方法的成本很高,需要了解和熟练掌握分布式系统。为了使用所有开发人员能够使用任何语言和任何框架轻松地构建便携式微服务应用程序,无论是开发新项目还是迁移现有代码

Dapr 介绍

Github:  https://github.com/dapr/dapr

Dapr是一种可移植的,事件驱动的,无服务器运行时,用于构建跨云和边缘的分布式应用程序。

Distributed Application Runtime. An event-driven, portable runtime for building microservices on cloud and edge.

640?wx_fmt=jpeg

其中提到了多语言和多开发者框架,我认为这是他选择的通过通信共享信息,即 HTTP 和 GRPC 支持多语言等特性。微软想通过这个设定一个构建微服务应用的规则。从根本上确立你开发的每一个应用的独立性。赋能每个开发者,为了使Dapr对于不同的语言更加方便,它还包括针对Go,Java,JavaScript,.NET和Python的语言特定的SDK。这些SDK通过类型化的语言API(而不是调用http / gRPC API)公开了Dapr构建块中的功能,例如保存状态,发布事件或创建actor。这使开发人员可以使用他们选择的语言编写无状态和有状态功能以及参与者的组合。并且由于这些SDK共享Dapr运行时,您甚至可以获得跨语言的actor和功能支持!

640?wx_fmt=png

Dapr还可以与任何开发人员框架集成。例如,在Dapr .NET SDK中,您将找到ASP.NET Core集成,该集成带来了可响应其他服务的发布/订阅事件的状态路由控制器,从而使ASP.NET Core成为构建微服务Web应用程序的更好框架。 

不过需要注意的是Dapr目前正处于Alpha阶段, 今天刚发布了0.2版本。在v1.0稳定版本发布之前,建议不要用于生产环境。 

下面进行一个 QuickStart

环境

  1. Install Docker(微服务已经离不开容器化了)

  2. Install Dapr CLI

  3. Install .Net Core SDK 3.0

在Windows 上通过Powershell 安装:

powershell -Command "iwr -useb https://raw.githubusercontent.com/dapr/cli/master/install/install.ps1 | iex"
然后把 c:\dapr 添加到环境变量 PATH
运行dapr命令,检查输出是否正常

C:\workshop\Github\dotnet-sdk>dapr --help

         __
     ____/ /___ _____  _____
    / __  / __ '/ __ \/ ___/
   / /_/ / /_/ / /_/ / /    
   \__,_/\__,_/ .___/_/
               /_/

======================================================
A serverless runtime for hyperscale, distributed systems

Usage:
   dapr [command]

Available Commands:
   help        Help about any command
   init        Setup dapr in Kubernetes or Standalone modes
   list        List all dapr instances
   publish     publish an event to multiple consumers
   run         Launches dapr and your app side by side
   send        invoke a dapr app with an optional payload
   stop        Stops a running dapr instance and its associated app
   uninstall   removes a dapr installation

Flags:
   -h, --help      help for dapr
       --version   version for dapr

Use "dapr [command] --help" for more information about a command.


执行初始化(会启动 docker 容器)
dapr init 
Making the jump to hyperspace... 
Downloading binaries and setting up components 
Success! Dapr is up and running
下载.NET SDk代码
https://github.com/dapr/dotnet-sdk ,里面有.NET Core的多个示例代码:
示例描述
1. ActorDemonstrates creating virtual actors that encapsulate code and state. Also see docs in this repo for a tutorial.
2. ASP.NET CoreDemonstrates ASP.NET Core integration with Dapr by create Controllers and Routes.
3. gRPC client

The gRPC client sample shows how to make Dapr calls to publish events, save state, get state and delete state using a gRPC client.

我们一起来看下ASP.NET Core的Demo;

例子中主 我们使用 Dapr 的交互。Dapr通过 Runtime

  • 提供 Dapr API 给多语言调用。

  • 提供 状态管理 By state stores


/// <summary>
  /// Sample showing Dapr integration with controller.
  /// </summary>
  [ApiController]
  public class SampleController : ControllerBase
  {
      /// <summary>
      /// Gets the account information as specified by the id.
      /// </summary>
      /// <param name="account">Account information for the id from Dapr state store.</param>
      /// <returns>Account information.</returns>
      [HttpGet("{account}")]
      public ActionResult<Account> Get(StateEntry<Account> account)
      {
          if (account.Value is null)
          {
              return this.NotFound();
          }

         return account.Value;
      }


     /// <summary>
      /// Method for depositing to account as psecified in transaction.
      /// </summary>
      /// <param name="transaction">Transaction info.</param>
      /// <param name="stateClient">State client to interact with dapr runtime.</param>
      /// <returns>A <see cref="Task{TResult}"/> representing the result of the asynchronous operation.</returns>
      [Topic("deposit")]
      [HttpPost("deposit")]
      public async Task<ActionResult<Account>> Deposit(Transaction transaction, [FromServices] StateClient stateClient)
      {
          var state = await stateClient.GetStateEntryAsync<Account>(transaction.Id);
          state.Value ??= new Account() { Id = transaction.Id, };
          state.Value.Balance += transaction.Amount;
          await state.SaveAsync();
          return state.Value;
      }


     /// <summary>
      /// Method for withdrawing from account as specified in transaction.
      /// </summary>
      /// <param name="transaction">Transaction info.</param>
      /// <param name="stateClient">State client to interact with dapr runtime.</param>
      /// <returns>A <see cref="Task{TResult}"/> representing the result of the asynchronous operation.</returns>
      [Topic("withdraw")]
      [HttpPost("withdraw")]
      public async Task<ActionResult<Account>> Withdraw(Transaction transaction, [FromServices] StateClient stateClient)
      {
          var state = await stateClient.GetStateEntryAsync<Account>(transaction.Id);

         if (state.Value == null)
          {
              return this.NotFound();
          }

         state.Value.Balance -= transaction.Amount;
          await state.SaveAsync();
          return state.Value;
      }
  }


这里重点是状态存储,即将 state 通过 StateClient 存储在 Dapr 中,我们通过状态转移在 Dapr 里实现了 stateless。
 
Dapr 运行.NET 应用程序

演示Dapr的服务调用,在终端中切换到项目目录,然后使用dapr启动应用


C:\workshop\Github\dotnet-sdk\samples\AspNetCore\ControllerSample>dapr run --app-id routing --app-port 5000 dotnet run    
Starting Dapr with id routing. HTTP Port: 61102. gRPC Port: 61103
You're up and running! Both Dapr and your app logs will appear here.


注意: 以上dapr run命令,通过app-id指定了应用的ID,通过app-port指定了应用的端口(webapi默认使用5000作为http端口),后跟dotnet run命名启动当前项目。可参考Dapr文档服务调用


后台运行的 CLI 命令,这里是前台打印的日志, 注意到 .NET App 在指定的 5000 端口运行,同时还有状态存储的 redis 在 6379 端口运行


== DAPR == time="2019-11-16T18:33:22+08:00" level=info msg="starting Dapr Runtime -- version 0.2.0 -- commit c75b11
1-dirty"
     == DAPR == time="2019-11-16T18:33:22+08:00" level=info msg="log level set to: info"
== DAPR == time="2019-11-16T18:33:22+08:00" level=info msg="standalone mode configured"
== DAPR == time="2019-11-16T18:33:22+08:00" level=info msg="dapr id: routing"
== DAPR == time="2019-11-16T18:33:22+08:00" level=info msg="loaded component messagebus (pubsub.redis)"        
     == DAPR == time="2019-11-16T18:33:22+08:00" level=info msg="loaded component statestore (state.redis)"
     == DAPR == time="2019-11-16T18:33:22+08:00" level=info msg="application protocol: http. waiting on port 5000"
     == APP == info: Microsoft.Hosting.Lifetime[0]
     == APP ==       Now listening on: http://localhost:5000
== APP == info: Microsoft.Hosting.Lifetime[0]
== APP ==       Application started. Press Ctrl+C to shut down.
     == APP == info: Microsoft.Hosting.Lifetime[0]
== APP ==       Hosting environment: Development
== APP == info: Microsoft.Hosting.Lifetime[0]
== APP ==       Content root path: C:\workshop\Github\dotnet-sdk\samples\AspNetCore\ControllerSample
     == DAPR == time="2019-11-16T18:33:31+08:00" level=info msg="application discovered on port 5000"
     == DAPR == 2019-11-16 18:33:32.029764 I | redis: connecting to localhost:6379
     == DAPR == 2019-11-16 18:33:32.036316 I | redis: connected to localhost:6379 (localAddr: [::1]:61164, remAddr: 
[::1]:6379)
     == DAPR == time="2019-11-16T18:33:32+08:00" level=info msg="actor runtime started. actor idle timeout: 1h0m0s. 
actor scan interval: 30s"
     == DAPR == time="2019-11-16T18:33:32+08:00" level=info msg="actors: starting connection attempt to placement se
rvice at localhost:6050"
== DAPR == time="2019-11-16T18:33:32+08:00" level=info msg="http server is running on port 61102"
== DAPR == time="2019-11-16T18:33:32+08:00" level=info msg="gRPC server is running on port 61103"
     == DAPR == time="2019-11-16T18:33:32+08:00" level=info msg="local service entry announced"
== DAPR == time="2019-11-16T18:33:32+08:00" level=info msg="dapr initialized. Status: Running. Init Elapsed 917
6.5164ms"
== DAPR == time="2019-11-16T18:33:32+08:00" level=info msg="actors: established connection to placement service
  at localhost:6050"
== DAPR == time="2019-11-16T18:33:32+08:00" level=info msg="actors: placement order received: lock"
== DAPR == time="2019-11-16T18:33:32+08:00" level=info msg="actors: placement order received: update"
== DAPR == time="2019-11-16T18:33:32+08:00" level=info msg="actors: placement tables updated"
== DAPR == time="2019-11-16T18:33:32+08:00" level=info msg="actors: placement order received: unlock"
== APP == info: System.Net.Http.HttpClient.state.LogicalHandler[100]
== APP ==       Start processing HTTP request GET http://localhost:61102/v1.0/state/17
== APP == info: System.Net.Http.HttpClient.state.ClientHandler[100]
== APP ==       Sending HTTP request GET http://localhost:61102/v1.0/state/17
== APP == info: System.Net.Http.HttpClient.state.ClientHandler[101]
== APP ==       Received HTTP response after 2228.2998000000002ms - OK     
== APP == info: System.Net.Http.HttpClient.state.LogicalHandler[101]       
== APP ==       End processing HTTP request after 2257.3405000000002ms - OK
== APP == info: System.Net.Http.HttpClient.state.LogicalHandler[100]
== APP ==       Start processing HTTP request POST http://localhost:61102/v1.0/state
== APP == info: System.Net.Http.HttpClient.state.ClientHandler[100]
== APP ==       Sending HTTP request POST http://localhost:61102/v1.0/state
== APP == info: System.Net.Http.HttpClient.state.ClientHandler[101]
     == APP ==       Received HTTP response after 67.46000000000001ms - Created
== APP == info: System.Net.Http.HttpClient.state.LogicalHandler[101]
== APP ==       End processing HTTP request after 68.0343ms - Created
     == APP == info: System.Net.Http.HttpClient.state.LogicalHandler[100]
     == APP ==       Start processing HTTP request GET http://localhost:61102/v1.0/state/17
== APP == info: System.Net.Http.HttpClient.state.ClientHandler[100]
== APP ==       Sending HTTP request GET http://localhost:61102/v1.0/state/17
== APP == info: System.Net.Http.HttpClient.state.ClientHandler[101]
== APP ==       Received HTTP response after 5.8247ms - OK
== APP == info: System.Net.Http.HttpClient.state.LogicalHandler[101]
== APP ==       End processing HTTP request after 6.268400000000001ms - OK
== APP == info: System.Net.Http.HttpClient.state.LogicalHandler[100]
== APP ==       Start processing HTTP request POST http://localhost:61102/v1.0/state
== APP == info: System.Net.Http.HttpClient.state.ClientHandler[100]
== APP ==       Sending HTTP request POST http://localhost:61102/v1.0/state
== APP == info: System.Net.Http.HttpClient.state.ClientHandler[101]
== APP ==       Received HTTP response after 4.5181000000000004ms - Created
== APP == info: System.Net.Http.HttpClient.state.LogicalHandler[101]
== APP ==       End processing HTTP request after 4.6208ms - Created
== APP == info: System.Net.Http.HttpClient.state.LogicalHandler[100]
== APP ==       Start processing HTTP request GET http://localhost:61102/v1.0/state/17
== APP == info: System.Net.Http.HttpClient.state.ClientHandler[100]
== APP ==       Sending HTTP request GET http://localhost:61102/v1.0/state/17
== APP == info: System.Net.Http.HttpClient.state.ClientHandler[101]
== APP ==       Received HTTP response after 20.2967ms - OK
== APP == info: System.Net.Http.HttpClient.state.LogicalHandler[101]
== APP ==       End processing HTTP request after 20.691100000000002ms – OK

为了同时实现可移植性和与现有代码的轻松集成,Dapr通过http或gRPC提供了标准API。Dapr端口可从Dapr启动日志中获取,如以下日志表示Dapr公开的HTTP端口为61102(通过Dapr也可使用gRPC方式进行服务调用)

== DAPR == time="2019-11-16T18:33:32+08:00" level=info msg="http server is running on port 61102"
== DAPR == time="2019-11-16T18:33:32+08:00" level=info msg="gRPC server is running on port 61103"

我们可通过以下地址来调用示例方法,根据Dapr服务调用API规范,其代理调用规则为:

POST/GET/PUT/DELETE http://localhost:<Dapr端口>/v1.0/invoke/<id>/method/<method-name>

直接调用:GET http://localhost:5000/17

通过Dapr服务调用: GET http://localhost:61102/v1.0/invoke/routing/method/17
 
注意: Dapr的服务调用是有dapr sidecar来实现的,在被调用的服务中无需注入任何与dapr相关的代码。


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

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

相关文章

.NET Core on K8S 学习与实践系列文章索引 (更新至20191116)

更新记录&#xff1a;-- 2019-11-16 增加Docker容器监控系列文章// 此外&#xff0c;今天是11月17日&#xff0c;我又老了一岁&#xff0c;祝我自己生日快乐&#xff01;近期在学习Kubernetes&#xff0c;基于之前做笔记的习惯&#xff0c;已经写了一部分文章&#xff0c;因此给…

身边的设计模式(一):单例 与 RedisCacheManager

大家好&#xff0c;以后我会用23篇文章&#xff0c;来给大家讲解设计模式&#xff0c;当然如果你看过我的项目&#xff0c;很多设计模式已经很会了&#xff0c;只是没有注意到&#xff0c;我这里会讲解一下&#xff0c;大家就会发现&#xff0c;如果你看懂了我的项目&#xff0…

Kubernetes包管理器Helm发布3.0版本

Helm 3.0 已经发布&#xff0c;该版本是 CLI 工具的最新主要版本&#xff0c;主要关注简单性、安全性和可用性&#xff0c;内容如下&#xff1a;新特性移除 Tiller&#xff08;Helm 2 是一种 Client-Server 结构&#xff0c;客户端称为 Helm&#xff0c;服务器称为 Ti…

“兼职”运维的常用命令

自从产品转到了 dotNET Core 之后&#xff0c;更深入的接触 Linux和 Docker &#xff0c;而我每天的工作中&#xff0c;有一部分时间相当于在“兼职”做一些运维的事情。下面是一些在日常中常用的命令&#xff0c;算是个备忘吧。环境操作系统&#xff1a;CentOS7Docker&#xf…

rabbitmq死信队列详解与使用

先从概念解释上搞清楚这个定义&#xff0c;死信&#xff0c;顾名思义就是无法被消费的消息&#xff0c;字面意思可以这样理解&#xff0c;一般来说&#xff0c;producer将消息投递到broker或者直接到queue里了&#xff0c;consumer从queue取出消息进行消费&#xff0c;但某些时…

使用ASP.NET Core 3.x 构建 RESTful API - 3.2 开始建立Controller和Action

Demo下面我们就来实践一下。打开之前的项目&#xff0c;并建立CompaniesController&#xff1a; 这里有6个地方比较关键&#xff0c;我们挨个看一下&#xff1a; RESTful API 或者其它Web API的Controller都应该继承于 ControllerBase 这个类&#xff08;点此查看详细的官方文档…

C++ 链表

线性表&#xff08;顺序表&#xff09;有两种存储方式&#xff1a;链式存储和顺式存储&#xff0c;顺式存储如数组&#xff0c;其内存连续分配&#xff0c;且是静态分配。链式存储&#xff0c;内存是不连续的&#xff0c;且是动态分配。前一个元素存储数据&#xff0c;后一个元…

波拉契尔数列 C++

题目&#xff1a;写一个函数&#xff0c;输入n, 求斐波那契数列的第n项。 分析&#xff1a;该题有两种实现方式递归或循环。当n比较大的时候f(n)结果也会比较大&#xff0c;故定义的时候可以采用long(int 也行)。递归会有大量的重复计算&#xff0c;而循环可以把f(n-1)和f(n-2)…

Deepin 下 使用 Rider 开发 .NET Core

国产的 Deepin 不错&#xff0c;安利一下。Deepin 用了也有一两年&#xff0c;也只是玩玩&#xff0c;没用在开发上面。后来 Win10 不太清真了&#xff0c;就想着能不能到 Deepin下撸码。要搞开发&#xff0c;首先少不了 IDE&#xff0c;VS2019 用不来&#xff0c;Vs Code 太复…

[视频演示].NET Core开发的iNeuOS物联网平台,实现从设备PLC、云平台、移动APP数据链路闭环...

此次我们团队人员对iNeuOS进行了全面升级&#xff0c;主要升级内容包括&#xff1a;&#xff08;1&#xff09; 设备容器增加设备驱动&#xff0c;包括&#xff1a;西门子&#xff08;S7-200smart、S7-300、S7-400、S7-1200、S7-1500&#xff09;、三菱&#xff08;FxSerial…

选择开源项目什么最重要?

开发人员在决定是否使用某个开源项目时考虑到的最重要事项是什么&#xff1f;代码质量&#xff1f;安全性&#xff1f;好的文档&#xff1f;上述因素都很重要&#xff0c;但根据 Tidelift 和 The New Stack 的联合调查&#xff0c;控制着开源项目的开源许可证才是最需要考量的因…

居然不知道和的区别?

前言那年刚找工作那会&#xff0c;就碰到过这么一个简单的题目“&和&&的区别” 那时知识面窄&#xff0c;大概也就知道1.都是作为逻辑与的运算符。2.&&具有短路功能&#xff0c;计算出前者false&#xff0c;就不需计算后者的true or false。后来在微信群里…

【DevOps进行时】自动化测试之单元测试

在DevOps建设中&#xff0c;主流的测试分层体系可以分为单元测试、接口测试和界面测试。Google曾提出一个经验法则&#xff1a;70%的小型测试&#xff0c;20%的中型测试&#xff0c;10%大型测试。当然&#xff0c;这个比例不是确定的&#xff0c;不同类型的项目&#xff0c;测试…

Zongsoft.Data 发布公告

很高兴我们的 ORM 数据访问框架(Zongsoft.Data)在历经两个 SaaS 产品的应用之后&#xff0c;今天正式宣布对外推广。它是一个类 GraphQL 风格的 ORM(Object/Relational Mapping) 数据访问框架。又一个轮子&#xff1f;在很长时间里&#xff0c;.NET 阵营似乎一直缺乏一个被普遍…

使用 .NET Core模板引擎创建自定义的模板和项目

本文要点.NET CLI 包含了一个模板引擎&#xff0c;它可以直接利用命令行创建新项目和项目项。这就是“dotnet new”命令。默认模板集涵盖了默认控制台和基于 ASP.NET 的应用程序以及测试项目所需的基本项目和文件类型。自定义模板可以创建更加有趣或定制化的项目和项目项&#…

.NET Core前后端分离快速开发框架(Core.3.0+AntdVue)

时间真快&#xff0c;转眼今年又要过去了。回想今年&#xff0c;依次开源发布了Colder.Fx.Net.AdminLTE(254Star)、Colder.Fx.Core.AdminLTE(335Star)、DotNettySocket(82Star)、IdHelper(47Star)&#xff0c;这些框架及组件都是本着以实际出发&#xff0c;实事求是的态度&…

.Net开发3年,应聘大厂惨遭淘汰,如何翻身打脸面试官?

(设计师忘记了&#xff0c;这里还有个双十一福利课&#xff0c;还能1元秒杀&#xff01;)

面对金九银十铜十一你真的准备好了吗?

作者&#xff1a;回首笑人间&#xff0c;高级Java工程师一枚&#xff0c;热爱研究开源技术&#xff0c;架构师社区合伙人&#xff01;前言&#xff1a;又是一年一度的金九银十跳槽季&#xff0c;回首在经历了半个月的求职奔波后&#xff0c;终于又能安稳的静下心来敲代码了&…

深入理解二叉搜索树

什么是二叉搜索树&#xff1f; 顾名思义&#xff0c;一颗二叉搜索树是基于二叉树来组织的&#xff0c;它包括许多动态集合操作&#xff08;Search&#xff0c;MiniNum, MaxiNum, Prodecessor, Successor, Insert 和Delete等&#xff09;。二叉搜索树上的基本操作所花费的时间与…

深入理解堆(最大堆,最小堆及堆排序)

基本概念&#xff1a; 1、完全二叉树&#xff1a;若二叉树的深度为h&#xff0c;则除第h层外&#xff0c;其他层的结点全部达到最大值&#xff0c;且第h层的所有结点都集中在左子树。 2、满二叉树&#xff1a;满二叉树是一种特殊的的完全二叉树&#xff0c;所有层的结点都是最…