Dapr(分布式应用程序运行时)是一个开源项目,它提供了一组 API 和工具,用于简化分布式应用程序开发。Dapr 可以轻松地与任何语言和框架集成,并与各种云、Kubernetes、服务器和边缘环境一起使用。Dapr 旨在帮助开发人员构建高度可扩展、可靠和可观测的分布式应用程序,而无需处理常见的分布式系统开发挑战。
Dapr 架构包含以下四个组件:
-
依赖注入器:Dapr 使用依赖注入器来将各个组件(如持久性、消息传递和状态管理)与应用程序逻辑分开。这使得应用程序更易于构建、测试和扩展。
-
应用程序代码:这是应用程序的实际业务逻辑,它使用 Dapr 中的组件来进行各种操作。
-
侧车代理:Dapr 侧车代理是一个用于处理应用程序与 Dapr 组件之间通信的进程。它运行在和应用程序相同的主机上,并处理各种通信协议,如 REST、gRPC 和消息传递。
-
组件:Dapr 组件是可插拔的模块,提供了与持久性、消息传递、状态管理、密钥管理等相关的功能。开发人员可以从现有的组件中选择,也可以开发自己的组件以适应特定需求。
总的来说,Dapr 架构提供了一种可扩展和灵活的方法,使得分布式应用程序的开发和部署变得更加容易和高效。
服务调用
Dapr 服务调用原理是基于 Dapr 的 sidecar 架构来实现的。Dapr Sidecar 是一个独立的进程,与应用程序在同一主机上运行,充当应用程序与其他服务之间的代理。当应用程序需要调用另一个服务时,它会将 API 调用发送给 Dapr sidecar。Sidecar 根据配置将请求路由到适当的服务,并将结果返回给应用程序。
Dapr 服务调用的支持可通过多种方式实现,包括 HTTP/REST、gRPC、和 RabbitMQ 等。Dapr sidecar 可以根据应用程序的配置使用任何一种方式来调用另一个服务。这使得应用程序可以轻松地集成和通信其他 Dapr 应用程序。
此外,Dapr 还提供了诸如服务发现、负载均衡和故障恢复等功能,以确保应用程序和其他服务之间的通信是可靠和高效的。这些功能使得开发人员可以更轻松地构建分布式应用程序,同时保持代码的简洁和灵活性。
以下是一个 Dapr 服务调用示例代码:
using Dapr.Client;
using System;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;
namespace DaprServiceInvocationSample
{
class Program
{
static async Task Main(string[] args)
{
var daprClient = new DaprClientBuilder().UseHttpEndpoint("http://localhost:3500").Build();
// Call an API on another Dapr service
var data = new { name = "John" };
var requestData = JsonSerializer.Serialize(data);
var response = await daprClient.InvokeMethodAsync<object>("otherservice", "api/v1/myendpoint", HttpInvocationMethod.Post, new StringContent(requestData));
Console.WriteLine($"Response: {response}");
}
}
}
这个示例会向 http://localhost:3500
发送一个 Dapr Invoke 请求,调用 ID 为 otherservice
的服务,服务的 API 端点为 api/v1/myendpoint
,请求方法为 POST
,请求数据为 {"name": "John"}
。Dapr 会将这个请求转发给 otherservice
服务,并返回响应结果。由于响应结果的类型已经指定为 object
,因此这里不对响应结果做反序列化。
pub/sub
Dapr(Distributed Application Runtime)是一种开源的微服务框架,它提供了一种解决方案来简化微服务应用程序中的开发和管理。其中,Dapr的pub/sub机制是其中一个重要的特性。
Dapr的pub/sub机制是一个基于消息传递的模式,用于在不同的服务之间进行异步通信。其基本原理如下:
-
发布者将消息发送到一个消息代理(message broker)中,消息代理将消息存储在其中。
-
订阅者告诉消息代理,它们想要接收哪些类型的消息。
-
当一个消息符合订阅者指定的类型时,消息代理将该消息传递给所有订阅者。
-
订阅者处理该消息,并可能产生反馈消息,将其发送回消息代理中,以便其他服务可以接收到该消息。
在Dapr中,消息代理可以是任何实现了Dapr pub/sub API的消息代理。Dapr提供了对多种消息代理的支持,包括Azure Service Bus、RabbitMQ、Kafka等。
总的来说,Dapr的pub/sub机制提供了一种灵活、可靠的异步通信方式,可帮助微服务之间更好地协作和相互沟通。
下面是Dapr的pub/sub示例代码,使用C#编写:
using System;
using System.Text.Json;
using System.Threading.Tasks;
using Dapr.Client;
using Microsoft.Extensions.Logging;
namespace PubSubExample
{
class Program
{
static async Task Main(string[] args)
{
var daprClient = new DaprClientBuilder().Build();
while (true)
{
// Listen for a new message on the "mytopic" topic
var message = await daprClient.PublishEventAsync("mytopic", new { message = "Hello Dapr!" });
Console.WriteLine($"Published message with ID: {message.Id}");
// Wait 5 seconds before sending the next message
await Task.Delay(5000);
}
}
}
}
该示例代码实现了一个发布者,它每隔5秒发布一条消息到名为“mytopic”的主题中。您需要确保已在运行中的Dapr实例中启用了pub/sub组件。要运行此示例,请使用以下命令:
dapr run --app-id publisher -- dotnet run
注意:在运行此示例之前,您需要先在您的开发环境中安装Dapr。
binding
Dapr 绑定(bindings)是一种用于与外部资源进行交互(如消息队列、数据库、对象存储等)的机制。它允许 Dapr 应用程序通过绑定和外部资源进行通信,而无需直接与资源进行交互。这种方式可以使应用程序更易于编写、测试和部署。
Dapr 支持多种类型的绑定,包括输出绑定(Output Bindings)、输入绑定(Input Bindings)和状态绑定(State Bindings)。在这些绑定之中,Bindings 可以使应用程序将状态写入到外部存储中,或者从外部存储中读取状态,还可以将应用程序的消息发送到外部消息队列。
Dapr Bindings的工作原理如下:
-
应用程序使用 Dapr 提供的 Binding API 连接到 Dapr 运行时。这个 API 允许应用程序指定要使用的绑定类型,以及相应的配置信息。
-
Dapr 运行时使用这些配置信息创建绑定,以便应用程序与外部资源进行交互。
-
应用程序使用绑定 API 与外部资源进行交互,例如读取和写入数据。
-
Dapr 运行时从绑定中获取数据,并将其传递给应用程序。或者,它将应用程序的数据发送到绑定,并将其写入外部资源。
以下是一个示例代码:
using Dapr;
using Dapr.Client;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
namespace DaprSample.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private readonly DaprClient daprClient;
public WeatherForecastController(DaprClient daprClient)
{
this.daprClient = daprClient;
}
[HttpPost("sendToQueue")]
public async Task<ActionResult> SendToQueue()
{
var message = new Message()
{
Data = new byte[] { 1, 2, 3 },
Metadata = new System.Collections.Generic.Dictionary<string, string>()
{
{ "Content-Type", "application/octet-stream" }
}
};
await daprClient.InvokeBindingAsync("myQueue", "create", message);
return Ok();
}
}
}
在上面的示例代码中,我们使用了 Dapr 客户端库来发送消息到队列绑定。具体来说,我们在 SendToQueue
方法中,创建了一个包含一些元数据和消息数据的 Message 对象,并使用 InvokeBindingAsync
方法将其发送到名为 myQueue
的队列绑定中。注意,create
是指定操作类型的参数。在本例中,我们正在创建一个新的消息,但是我们还可以使用不同的操作类型来执行其他操作(例如删除、更新等)。
state management
Dapr (Distributed Application Runtime) 是一个开源框架,用于构建微服务应用程序。其中,State Management 是 Dapr 的一个组件,用于管理分布式系统中的数据状态。
Dapr State Management 使用 Dapr 提供的分布式状态存储服务,如 Redis、Azure Cosmos DB、Etcd 等,存储应用程序中的状态数据。这些服务支持 ACID 事务,并可作为一个集群使用。Dapr 根据应用程序的需求,自动将状态数据存储在最适合的服务上。
下面是一个使用 Dapr State Management 的示例代码:
using Dapr.Client;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
namespace DaprDemo.Controllers
{
[ApiController]
[Route("[controller]")]
public class StateController : ControllerBase
{
private readonly DaprClient _daprClient;
public StateController(DaprClient daprClient)
{
_daprClient = daprClient;
}
[HttpGet("{key}")]
public async Task<string> Get(string key)
{
return await _daprClient.GetStateAsync<string>("statestore", key);
}
[HttpPost("{key}")]
public async Task Set(string key, [FromBody] string value)
{
await _daprClient.SaveStateAsync("statestore", key, value);
}
}
}
以上代码演示了一个通过 HTTP 请求访问 Dapr State Management 组件的应用程序。其中,DaprClient
类提供了与 Dapr 计划中的组件进行交互的功能。在该类中,GetStateAsync
方法用于获取状态数据,SaveStateAsync
方法用于保存状态数据。
在 Get
方法中,应用程序从名为 statestore
的状态存储服务中获取指定键的值,并返回该值作为 HTTP 响应的正文。在 Set
方法中,应用程序将传递的值保存在名为 statestore
的状态存储服务中,该键为 key
。
Actor模型
Dapr Actor模型是一种可扩展、高可用性的分布式应用程序模型,用于处理复杂的并发和并行计算。它基于Actor模型,其中每个Actor都是一个独立的计算单元,它们通过消息传递进行通信。Dapr Actor模型提供了一种抽象层,使得Actors可以在任何平台上运行。
下面是一个简单的Dapr Actor模型示例代码,这个示例代码演示了如何使用C#语言创建一个Actor:
using Dapr.Actors;
using Dapr.Actors.Runtime;
using System.Threading.Tasks;
namespace MyActorService
{
public interface IMyActor : IActor
{
Task<string> GetActorIdAsync();
Task<int> AddAsync(int value);
}
public class MyActor : Actor, IMyActor
{
private int currentValue = 0;
public MyActor(ActorHost host) : base(host)
{
}
public Task<string> GetActorIdAsync()
{
return Task.FromResult(this.Id.GetId());
}
public Task<int> AddAsync(int value)
{
currentValue += value;
return Task.FromResult(currentValue);
}
}
}
在这个示例代码中,我们首先定义了一个Actor接口IMyActor,它继承自Dapr的IActor接口。在接口中我们定义了两个方法,一个用于获取Actor的ID,另一个用于执行加法操作。然后我们实现了这个接口,创建了一个名为MyActor的Actor类,并实现了IMyActor接口的方法。在AddAsync方法中,我们将接收到的值添加到当前值中,并返回新的结果。
通过这个Dapr Actor模型示例代码,我们可以看到如何使用C#语言来创建Actor,并实现Actor的方法。这个示例代码只是一个简单的入门示例,Dapr Actor模型还有更多的高级功能和选项,可以根据具体需求进行使用。
Dapr observability
Dapr 是一个开源的运行时框架,可以帮助开发者简化应用程序的构建和管理。其中 Observability 模块提供了对应用程序运行时状态的可观察性支持,包括数据收集、分析和可视化。
Dapr Observability 的原理是通过使用指标(Metrics)、跟踪(Tracing)和日志(Logging)来监视应用程序的工作情况。Dapr 可以通过不同的插件与多种数据收集工具和分析工具集成,例如 Prometheus、Zipkin 或 Jaeger 等。
以下是使用 Dapr Observability 的示例代码(基于 .NET Core):
- 在应用程序中添加 Dapr Observability 插件:
using Dapr.Extensions.Configuration;
using Dapr.Extensions.Logging;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace MyApp
{
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddDaprClient();
services.AddDaprObservability();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
{
app.UseCloudEvents();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseDaprObservability();
loggerFactory.AddDapr(Configuration.GetSection("DaprLogging"));
}
}
}
- 配置 Dapr Observability 插件:
{
"DaprObservability": {
"Enabled": true,
"MetricsExporter": {
"Type": "Prometheus",
"Options": {
"Endpoint": "http://localhost:9090/"
}
},
"TracingExporter": {
"Type": "Zipkin",
"Options": {
"Endpoint": "http://localhost:9411/api/v2/spans",
"ServiceName": "MyApp"
}
},
"LoggingExporter": {
"Type": "JsonFile",
"Options": {
"Path": "logs.json"
}
}
}
}
此配置将启用 Dapr Observability,在应用程序中使用 Prometheus、Zipkin 和 JSON 文件作为指标、跟踪和日志的导出目标。
- 在应用程序中使用指标:
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
namespace MyApp.Controllers
{
[ApiController]
[Route("[controller]")]
public class MyController : ControllerBase
{
private readonly ILogger<MyController> _logger;
public MyController(ILogger<MyController> logger)
{
_logger = logger;
}
[HttpGet]
public IActionResult Get()
{
_logger.LogInformation("MyController.Get executed");
Metrics.MeasureGauge("MyController.Get.ExecutionTime", 1);
return Ok();
}
}
}
此代码将记录日志并测量“MyController.Get.ExecutionTime”指标的值。
- 在应用程序中使用跟踪:
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
namespace MyApp.Controllers
{
[ApiController]
[Route("[controller]")]
public class MyController : ControllerBase
{
private readonly ILogger<MyController> _logger;
public MyController(ILogger<MyController> logger)
{
_logger = logger;
}
[HttpGet]
public IActionResult Get()
{
using var scope = Tracing.BeginScope("MyController.Get");
_logger.LogInformation("MyController.Get executed");
return Ok();
}
}
}
此代码将开始跟踪并记录日志。
总之,Dapr Observability 可以帮助开发者了解应用程序的工作情况,并与不同的数据收集和分析工具进行集成。以上是针对 Dapr Observability 的原理和示例代码的简单介绍。如果你需要更多信息,请参阅 Dapr Observability 文档:https://docs.dapr.io/developing-applications/building-blocks/observability/。
secrets management
Dapr的Secrets Management提供了一种安全地存储和访问敏感信息(例如密码,API密钥等)的方式。它可以在本地文件系统,Azure Key Vault,HashiCorp Vault等外部存储中存储和获取机密。
Dapr Secrets Management的工作原理是在Dapr应用程序中定义机密并访问它们。应用程序可以在配置文件中定义机密并指定它们的名称和类型。通过使用Dapr的secrets API,应用程序可以在需要时访问机密,而无需暴露敏感信息。Dapr将自动获取机密,并在应用程序中使用它们。
以下是在Dapr中使用secrets API的一个简单示例。
- 在Dapr应用程序的配置文件中添加机密的定义。例如,要在Azure Key Vault中存储一个密码,配置可以如下所示:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: my-app-config
spec:
secrets:
- storeName: azurekeyvault
properties:
vaultName: my-key-vault
- alias: my-password
key: /secrets/my-secret/password
storeName: azurekeyvault
在此配置中,我们定义了一个名为’azurekeyvault’的存储。我们还定义了一个名为’my-password’的机密,它存储在’/secrets/my-secret/password’路径下。这个机密将存储在Azure Key Vault中。
- 在应用程序中使用机密。以下是一个示例代码片段,它从Azure Key Vault中检索’my-password’机密,并使用它来访问另一个服务。
using Dapr.Client;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
[ApiController]
[Route("[controller]")]
public class MyController : ControllerBase
{
private readonly DaprClient daprClient;
public MyController(DaprClient daprClient)
{
this.daprClient = daprClient;
}
[HttpGet("password")]
public async Task<ActionResult<string>> GetPassword()
{
string password = await daprClient.GetSecretAsync("azurekeyvault", "my-password");
// Use the password to access another service
return Ok(password);
}
}
在此示例代码中,我们使用DaprClient的GetSecretAsync方法来检索’my-password’机密。我们可以将返回的密码用于访问另一个服务。
以上是使用Dapr Secrets Management的一个简单示例。使用Dapr Secrets Management,您可以轻松地安全地管理和访问敏感信息,而无需暴露它们的真实值。
多运行时微服务架构
多运行时微服务架构和Dapr(Distributed Application Runtime)之间的联系在于,Dapr是一种开源的、可移植的、事件驱动的微服务运行时,它可以轻松地集成到多种不同类型的运行时中。
具体而言,Dapr使用了一些可插拔的组件,例如:pub-sub、持久化、服务间调用、状态管理等,这些组件可以在多个运行时上部署,这包括Kubernetes、Azure、AWS、GCP等。
多运行时微服务架构的核心思想是通过不同的运行时来提供不同的功能,以便在不同的环境中使用各种不同的应用程序。Dapr架构可以与多运行时架构集成,因为它提供了一个通用的微服务运行时层,可以用于不同的运行时中。
因此,Dapr可以被视为通用的微服务运行时,可以在多种不同类型和多个不同的运行时中部署。这使得Dapr成为多运行时微服务架构的有力补充,同时也为多运行时架构提供了更多的灵活性和可移植性。
公众号
更多内容,欢迎关注我的微信公众:半夏之夜的无情剑客。