Dapr for dotnet | 输入/输出绑定 - Input/Output Bindings

Dapr 绑定(Bindings)介绍

基于云的 Serverless 产品/服务(如 Microsoft Azure Function 和 Amazon AWS Lambda)已在分布式体系结构领域获得了广泛的应用。 它们有一个优势是 使微服务能够处理来自外部系统的事件或在外部系统中调用事件 ,从而 消除了底层复杂性和管道问题

Serverless 基本概念入门参考 =》https://www.infoq.cn/article/s101GtcCV05_2AgKo8GD

外部资源有很多:它们包括跨不同平台和供应商的数据存储、消息系统和 Web 资源。 Dapr 绑定(Bindings)构建基块将这些相同的资源绑定功能引入 Dapr 应用程序的门阶。

Dapr 绑定(Bindings)具备的优点

  • 排除连接到消息传递系统 ( 如队列和消息总线 ) 并进行轮询的复杂性
  • 聚焦于业务逻辑,而不是如何与系统交互的实现细节
  • 使代码不受 SDK 或库的跟踪
  • 处理重试和故障恢复
  • 在运行时在绑定之间切换
  • 构建具有特定于环境的绑定的可移植应用程序,不需要进行代码更改

Dapr 绑定的用途

绑定提供了一种常用方法,用于使用来自外部系统的事件触发应用程序,或使用可选的数据负载调用外部系统。绑定非常适合事件驱动的按需计算,并有助于减少样板代码

通过 Dapr 资源绑定,你的服务可以在直接应用程序之外的外部资源中整合业务操作。

  • 外部系统触发(输入绑定,Input Binding):来自外部系统的事件可以触发你的服务中的操作,传递上下文信息。
  • 内部系统触发(输出绑定,Output Binding):你的服务可以扩展操作,触发另一个外部系统中的事件,传递上下文有效负载信息。

你的 服务在没有耦合或感知外部资源的情况下进行通信。 管道封装在预定义的 Dapr 组件中。 要使用的 Dapr 组件可在运行时轻松地进行交换,无需更改代码

例如,用户通过推文发送关键字信息时事件触发了 Twitter 帐户(触发 Dapr 的 Sidecar API),Your service 公开用于接收和处理推文的事件处理程序。 完成后,Your service 将触发( Dapr 的 Sidecar API)调用外部 Twilio 服务的事件。驱动 Twilio 发送一条包含该推文的短信。
Bindings

输入绑定(Input Bindings)

输入绑定用于在发生来自外部资源的事件时触发应用程序。 可选的有效负载和元数据可以与请求一起发送。

为了接收来自输入绑定的事件:

  1. 定义描述绑定类型及其元数据 ( 连接信息等) 的组件 YAML;
  2. 监听传入事件的 HTTP 终结点(Endpoint),或使用 gRPC 原型库获取传入事件;

输入绑定
执行步骤如下:

  1. Dapr sidecar 读取绑定配置文件并订阅为外部资源指定的事件。 在示例中,事件源是 Twitter 帐户。
  2. 在 Twitter 上发布匹配的推文时,在 Dapr sidecar 中运行的绑定组件会选取它并触发事件。
  3. Dapr sidecar 调用终结点 (即为绑定) 事件处理程序。 在示例中,服务侦听端口6000 上的终结点(/tweet)上的 HTTP POST。 由于它是 HTTP POST 操作,因此事件的 JSON 有效负载在请求正文中传递。
  4. 处理事件后,服务将返回 HTTP 状态代码 200 OK。

如果操作应出错,将返回相应的 400 或 500 级别 HTTP 状态代码。 对于具有 至少 一次语义 传递保证的绑定,Dapr sidecar 将重试触发器。

输出绑定(Output Binding)

输出绑定允许用户调用外部资源。 可选的有效负载和元数据可与调用请求一起发送。

为了调用输出绑定:

  1. 定义描述绑定类型及其元数据 ( 连接信息等) 的组件 YAML;
  2. 使用 HTTP 终结点(Endpoint)或 gRPC 方法调用具有可选有效负载的绑定;

Output Binding
执行步骤如下:

  1. Dapr sidecar 读取绑定 Yaml 配置文件,并提供有关如何连接到外部资源的信息。 在示例中,外部资源是 Twilio SMS 帐户。
  2. 应用程序调用【/v1.0/bindings/sms】Dapr sidecar 上的终结点(Endpoint)。 在这种情况下,它使用 HTTP POST 调用 API,也可使用 gRPC。
  3. Dapr sidecar 中运行的绑定组件调用外部消息传送系统来发送消息。 该消息将包含 POST 请求中传递的有效负载。

资源绑定行为 & 发布/订阅模式的类比

两者有相似之处,但也有区别。

  • 发布/订阅(Pub/Sub) 侧重于 Dapr 服务之间的 异步通信
  • 资源绑定(Input/Output Bindings) 涉及的范围更广。 它侧重于软件平台之间的 系统互操作性

资源绑定(Input/Output Bindings)在微服务应用程序之外的不同应用程序、数据存储和服务之间交换信息。

Dapr 资源绑定的 API

由于 dapr 的运行时 daprd 是采用 go 语言编写的,所以下面的 API 均由 go 提供。

  • 输入绑定
type InputBinding interface {
	Init(metadata Metadata) error
	Read(handler func(*ReadResponse) ([]byte, error)) error
}
  • 输出绑定
type OutputBinding interface {
	Init(metadata Metadata) error
	Invoke(req *InvokeRequest) (*InvokeResponse, error)
	Operations() []OperationKind
}

输出绑定可用于调用外部系统,也可以从中返回数据。每个输出绑定都可以决定它支持哪些操作。此信息通过该方法传达给调用方。Operations()

创建输出绑定时,需要返回项列表。例如,如果运行的组件接受 SQL 查询并返回结果集,则可以是 OperationKind,OperationKind,query

虽然组件不限于受支持的操作列表,但如果操作类型属于该操作定义,则最好使用常见组件。

更多 Dapr 绑定资源组件支持情况,请查看 =》https://docs.dapr.io/reference/components-reference/supported-bindings/

在 .NET 中使用 Dapr Bindings

以下代码继续以 BackEnd 项目环境为例,新增如下代码信息。

添加输入/输出绑定代码

  • 新增 DaprBindingsController 的 API,添加如下代码:
using Dapr.Client;
using Microsoft.AspNetCore.Mvc;
using System.Text;

namespace FrontEnd.Controllers;

[Route("api/[controller]")]
[ApiController]
public class DaprBindingsController : ControllerBase
{
    private readonly ILogger<DaprBindingsController> _logger;
    public DaprBindingsController(ILogger<DaprBindingsController> logger)
    {
        _logger = logger;
    }

    /// <summary>
    /// 输入绑定
    /// </summary>
    /// <returns></returns>
    [HttpPost("Input")]
    public async Task<ActionResult> InputAsync()
    {
        byte[] buffer = new byte[Request.ContentLength.Value];
        using Stream stream = Request.Body;
        stream.Position = 0L;
        await stream.ReadAsync(buffer, 0, buffer.Length);
        string content = Encoding.UTF8.GetString(buffer);
        _logger.LogInformation($"{DateTime.Now} ,binding(InputAsync) ===> { content }");
        return Ok();
    }

    /// <summary>
    /// 输出绑定
    /// operation 操作类型:create,get,delete,list
    /// </summary>
    /// <param name="daprClient"></param>
    /// <returns></returns>
    [HttpGet("Output")]
    public async Task<ActionResult> OutputAsync([FromServices] DaprClient daprClient,string data)
    {
        _logger.LogInformation($"{DateTime.Now} ,binding(OutputAsync) ===> {data}");
        await daprClient.InvokeBindingAsync("api/DaprBindings/Output", "create", $"{DateTime.Now} ===> {data}");
        return Ok();
    }
}

添加 yaml 组件配置

组件配置的 yaml 文件,在 self-hosted 模式中,通常存放于如下位置

C:\Users\<username>\.dapr\components
  • 添加 rabbitmq-input-binding.yaml 配置
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: api/DaprBindings/Input # 务必和 api 接口路由一致;
spec:
  type: bindings.rabbitmq
  version: v1
  metadata:
  - name: queueName # 队列名称
    value: queue-for-input-binding # 输入绑定的队列名称
  - name: host # mq 主机
    value: amqp://mqtest:test123@192.168.30.71:5672 # rabbitmq 连接地址(带密码)
  • 添加 rabbitmq-output-binding.yaml 配置
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: api/DaprBindings/Output
spec:
  type: bindings.rabbitmq
  version: v1
  metadata:
  - name: queueName
    value: queue-for-output-binding
  - name: host
    value: amqp://mqtest:test123@192.168.30.71:5672

绑定服务测试

  • 启动 BackEnd 服务
dapr run --dapr-grpc-port 50010 --dapr-http-port 3510 --app-port 5001 --app-id backend dotnet run
  • 浏览器查看 swagger 页面
http://localhost:5001/swagger/index.html

DaprBindings

  • 浏览器查看 RabbitMQ 管理界面

绑定队列名称

输入绑定队列名称:queue-for-input-binding
输出绑定队列名称:queue-for-output-binding

  • 测试输入绑定,rabbitmq 管理页面 publish 一条消息

rabbitmq-input-binding

  • 测试输出绑定,在 swagger 页面接口写入消息操作,显示如下信息:

rabbitmq-output-binding

curl 命令执行:

curl -X 'GET' \
  'http://localhost:5001/api/DaprBindings/Output?data=dapr-uotput-6661' \
  -H 'accept: */*'
  • 查看 rabbitmq 中的输出绑定队列,已经有消息产生

在这里插入图片描述

总结

使用 Dapr 的 Bindings 构建块,整个代码的可以移植性明显增强,大大减少了传统 SDK 模式的代码量,同时还抽象了使用外部资源组件的能力,同等能力的组件在运行时无缝切换,并且整个过程无需维护第三方资源组件的连接通信代码,只需要配置对应的 yaml 文件即可,让开发人员有更多的精力专注于业务本体的代码编写;

推荐参考文章

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ChaITSimpleLove

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值