Dapr云原生应用开发系列6:绑定构建块

题记:这篇介绍绑定构建块,这是一个极度简化应用程序本身代码的特性。本文在GitHub Copilot的帮助下书写。

原理

由于Dapr由微软Azure团队孵化,所以绑定这一概念也是来源于微软的开源Serverless项目Azure Functions。所以我们理解Dapr的绑定构建块,可以参考Azure Functions绑定的概念。

其中,Dapr的输入绑定即Azure Function的触发器;Dapr的输出绑定即Azure Function的输出绑定;但是Azure Function的输入绑定在Dapr中并没有对应概念。

通过输入绑定,我们可以让Dapr应用程序被外部事件触发,而不是像传统应用程序那样,需要自己去轮询外部事件源。通过输出绑定,我们可以让Dapr应用程序触发外部事件,而不是像传统应用程序那样,需要自己去调用外部事件源。另外通过输出绑定,也可以让Dapr应用程序把相关数据写入到外部服务。

如下图所示,我们可以通过输入绑定来接收来自于Kafka的消息:

976913481bc7b1a4098548672af233bc.png

或者,通过输出绑定来发送消息到Kafka:

48ee8dd4f75034e381e3dbf5d34a3a8d.png

当然输出绑定不是说只能发送消息到消息队列,也是可以写入数据到外部数据源,比如调用HTTP API,访问数据库,甚至通过SMTP协议来发送邮件。比如下图的例子中,通过定时器触发Dapr应用,Dapr应用写入数据到PostgreSQL里面:

12054e9f514579a55c7bb957ffd678f2.png

边车的作用

众所周知,Dapr构建块都是通过Dapr边车来提供能力的,绑定构建块也不例外。Dapr边车会在应用程序启动的时候,自动去注册绑定构建块所需要的输入和输出绑定。这样,应用程序就可以通过Dapr边车来使用绑定构建块的能力了。

Dapr边车会处理输入绑定的消息队列的连接,消息队列的消息实际上是发给Dapr边车,Dapr边车再请求Dapr应用程序匹配的路由接口(默认是和绑定名称一致的路由接口,也可以通过绑定定义yaml文件中设定不同的名称)。要特别注意的是,Dapr边车访问应用程序的接口,是需要获得 200 OK 才认为成功,不然会一直重试。所以应用程序需要很小心的处理异常(一般需要Catch后总是返回200),以避免Dapr边车进入死循环。还有一种特殊的情况是,如果使用诸如ASP.NET Core的模型绑定能力,那么要保证模型定义具备很强的兼容性,不然ASP.NET Core框架本身会返回400,导致Dapr边车进入死循环。

同样,Dapr边车会处理输出绑定的消息队列的连接,Dapr应用程序发送消息或写入数据实际上是发给Dapr边车,Dapr边车再转发给消息队列。Dapr边车会根据绑定定义yaml文件中的配置,来决定消息队列(或数据源)的类型和连接方式。

和发布订阅构建块PubSub的关系

大家应该看到,输入和输出绑定都可以和消息队列中间件结合,那么在这种情况下和PubSub的关系是什么呢?

我想主要区别在于:PubSub主要处理的是系统边界之内的消息(这些消息往往是广播的事件消息),而输入和输出绑定主要处理的是系统边界之外的消息(这些消息往往是点对点的数据消息)。

正因为这样的区别,所以两者在使用同一种消息队列中间件的时候,也会有不同的使用方式。比如发布订阅和绑定构建块都可以使用Azure Service Bus作为消息队列中间件,但是在使用的时候,发布订阅会使用Service Bus的Topic和Subscription(支持消息广播),而绑定构建块会使用Service Bus的Queue(支持点对点)。

能力

绑定目前支持的组件在这里可以查询到:https://docs.dapr.io/reference/components-reference/supported-bindings/

这个列表应该会不断的扩充。我在这里仅列出一些比较重要的组件。

输入绑定

  • Cron (Scheduler)

  • Kafka

  • RabbitMQ

  • Azure Service Bus Queues

  • Azure Storage Queues

输出绑定

  • HTTP

  • Kafka

  • PostgreSQL

  • RabbitMQ

  • Redis

  • SMTP

  • Azure Blob Storage

  • Azure Service Bus Queues

  • Azure Storage Queues

规范

绑定定义yaml文件

以Kafka为例,绑定定义yaml文件如下:

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: checkout
spec:
  type: bindings.kafka
  version: v1
  metadata:
  - name: brokers
    value: "http://localhost:5050"
  - name: topics
    value: "someTopic"
  - name: publishTopic
    value: "someTopic2"
  - name: consumerGroup
    value: "group1"
  - name: "direction"
    value: "input, output"

这个文件中,我们可以看到:

  • 通过 spec.type 字段来指定绑定的类型,这里是 bindings.kafka,也就是Kafka的输入输出绑定。

  • 通过 spec.metadata 字段来指定绑定的配置,这里是Kafka的特定配置,包括 brokerstopicspublishTopic 和 consumerGroup。不同绑定组件,可能具备不同的配置。

  • 通过 spec.metadata.direction (可选)字段来指定绑定的方向,这里是 input, output,也就是输入输出都支持。

  • 在实践当中,我们最好通过 scopes 限定一下组件的作用域,比如 scopes: ["myapp"],这样就只有在 dapr run --app-id myapp 的时候才会加载这个组件。避免无关的应用使用到不应该使用的组件。

注册输入绑定的触发接口

在定义了输入方向的绑定组件之后,就需要在应用中提供一个和组件名称一致(约定优先)的路由地址处理接口,来让外部可以触发应用程序的接口(也即接收消息队列的消息)。比如上面的Kafka绑定,就需要提供一个 /checkout 的路由地址。

以ASP.NET Core为例,我们可以这样实现这个接口:

//dependencies
using System.Collections.Generic;
using System.Threading.Tasks;
using System;
using Microsoft.AspNetCore.Mvc;

//code
namespace CheckoutService.controller
{
    [ApiController]
    public class CheckoutServiceController : Controller
    {
        [HttpPost("/checkout")]
        public ActionResult<string> getCheckout([FromBody] int orderId)
        {
            Console.WriteLine("Received Message: " + orderId);
            return "CID" + orderId;
        }
    }
}

调用输出绑定发送数据或消息

在定义了输出方向的绑定组件之后,就可以在应用中调用通过Dapr HTTP API调用如下地址:

POST/PUT http://localhost:<daprPort>/v1.0/bindings/<name>

并传递如下的JSON数据:

{
  "data": "some data",
  "operation": "create",//目前默认都是create这个值
  "metadata": {
    "key": "value"
  }
}

DOTNET SDK

.NET SDK提供了对输出绑定调用的封装,具体用法为:

string BINDING_NAME = "checkout";
string BINDING_OPERATION = "create";
using var client = new DaprClientBuilder().Build();
//Using Dapr SDK to invoke output binding
await client.InvokeBindingAsync(BINDING_NAME, BINDING_OPERATION, orderId);

用法与例子

用法和例子,可以参考官方文档:https://docs.dapr.io/developing-applications/building-blocks/bindings/

包括绑定的API规范文档:https://docs.dapr.io/reference/api/bindings_api/

也可以参考我的Quickstarts项目:https://github.com/heavenwing/dapr-dotnet-quickstarts/tree/main/BindingsWithSdk

实际场景

我在某个项目中把输入和输出绑定运用到了一个用户导入的实际场景中。

具体做法是:

  • 用户在前端上传一个Excel文件,后端接收到这个文件之后,会把这个文件的内容解析成一个个用户对象,然后把每个用户对象通过输出绑定发送到消息队列(Request队列)中;

  • 在一个外部的Azure Function中订阅Request队列中的数据,并创建出SSO用户,然后把创建结果发送到消息队列(Response队列)中;

  • 后端通过输入绑定来订阅Response队列中的数据,并把创建结果保存到数据库。

整个过程如下图所示:

c2beaa212805722ca2d3f5f5fca7c46a.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值