烂翻译系列之面向.NET开发人员的Dapr——绑定

The Dapr bindings building block

Dapr 绑定构建块

Cloud-based serverless offerings, such as Azure Functions and AWS Lambda, have gained wide adoption across the distributed architecture space. Among many benefits, they enable a microservice to handle events from or invoke events in an external system - abstracting away the underlying complexity and plumbing concerns. External resources are many: They include datastores, message systems, and web resources, across different platforms and vendors. The Dapr bindings building block brings these same resource binding capabilities to the doorstep of your Dapr applications.

基于云的 无服务产品(如 AZURE FUNCTIONS 和 AWS Lambda),在整个分布式体系结构领域获得广泛采用。 在许多方面,它们使微服务能够 处理来自 外部系统的事件或在外部系统 中调用事件 ,从而消除了底层复杂性和管道问题。 外部资源很多:它们包括跨不同平台和供应商的数据存储、消息系统和 web 资源。 Dapr 绑定构建块将这些资源绑定功能引入 Dapr 应用程序。

What it solves

解决方法

Dapr resource bindings enable your services to integrate business operations across external resources outside of the immediate application. An event from an external system could trigger an operation in your service passing in contextual information. Your service could then expand the operation by triggering an event in another external system, passing in contextual payload information. Your service communicates without coupling or awareness of the external resource. The plumbing is encapsulated inside pre-defined Dapr components. The Dapr component to use can be easily swapped at runtime without code changes.

通过 Dapr 资源绑定,服务可以将业务操作与应用程序之外的外部资源集成。 来自外部系统的事件可能会触发服务中的操作并传递上下文信息。 然后,你的服务可以通过在另一个外部系统中触发事件来展开操作,同时传递上下文负载信息。 你的服务不需要耦合或知道外部资源就进行通信。 该管道封装在预定义的 Dapr 组件中。 在运行时,可以轻松地替换 Dapr 组件,而无需更改代码。

Consider, for example, a Twitter account that triggers an event whenever a user tweets a keyword. Your service exposes an event handler that receives and processes the tweet. Once complete, your service triggers an event that invokes an external Twilio service. Twilio sends an SMS message that includes the tweet. Figure 8-1 show the conceptual architecture of this operation.

考虑一下,当用户推文时,Twitter 帐户触发事件 。 服务公开用于接收和处理推文的事件处理程序。 完成后,服务将触发调用外部 Twilio 服务的事件。 Twilio 发送包含推文的短信。 图8-1 显示了此操作的概念体系结构。

Figure 8-1. Conceptual architecture of a Dapr resource binding.

图 8-1。 Dapr 资源绑定的概念体系结构。

At first glance, resource binding behavior may appear similar to the Publish/Subscribe pattern described earlier in this book. While they share similarities, there are differences. Publish/subscribe focuses on asynchronous communication between Dapr services. Resource binding has a much wider scope. It focuses on system interoperability across software platforms. Exchanging information between disparate applications, datastores, and services outside your microservice application.

乍一看,资源绑定行为可能与本书前面介绍的 发布/订阅模式 类似。 尽管它们有相似之处,但也有不同之处。 发布/订阅侧重于 Dapr services 之间的异步通信。 资源绑定具有更大的范围。 它侧重于软件平台之间的系统互操作性。 在不同的应用程序、数据存储和微服务应用程序之外的服务之间交换信息。

How it works

工作原理

Dapr resource binding starts with a component configuration file. This YAML file describes the type of resource to which you'll bind along with its configuration settings. Once configured, your service can receive events from the resource or trigger events on it.

通过组件配置文件来使用Dapr 资源绑定。 此 YAML 文件描述绑定的资源类型。 配置后,你的服务可以接收来自资源的事件或触发事件。

Note

Binding configurations are presented in detail later in the Components section.

备注

稍后将在 " 组件 " 部分中详细介绍绑定配置。

Input bindings

输入绑定

Input bindings trigger your code with incoming events from external resources. To receive events and data, you register a public endpoint from your service that becomes the event handler. Figure 8-2 shows the flow:

输入绑定通过外部资源的传入事件触发代码。 若要接收事件和数据,请在服务中注册一个公共终结点作为 事件处理程序 。 图8-2 显示了工作流:

Figure 8-2. Dapr input binding flow.

图 8-2。 Dapr 输入绑定流。

Figure 8.2 describes the steps for receiving events from an external Twitter account:

  1. The Dapr sidecar reads the binding configuration file and subscribes to the event specified for the external resource. In the example, the event source is a Twitter account.
  2. When a matching Tweet is published on Twitter, the binding component running in the Dapr sidecar picks it up and triggers an event.
  3. The Dapr sidecar invokes the endpoint (that is, event handler) configured for the binding. In the example, the service listens for an HTTP POST on the /tweet endpoint on port 6000. Because it's an HTTP POST operation, the JSON payload for the event is passed in the request body.
  4. After handling the event, the service returns an HTTP status code 200 OK.

图8.2 介绍了从外部 Twitter 帐户接收事件的步骤:

  1. Dapr 边车读取绑定配置文件并订阅外部资源特定的事件。 在此示例中,事件源是一个 Twitter 帐户。
  2. 当在 Twitter 上发布了匹配的推文时,在 Dapr 边车中运行的绑定组件会捕捉到它并触发一个事件。
  3. Dapr 边车调用为绑定配置的终结点 (作为事件处理程序 ) 。 在此示例中,服务监听http://localhost:6000/tweet(POST)。 由于它是 HTTP POST 操作,因此在请求正文中传递事件的 JSON 负载。
  4. 处理事件后,服务将返回 HTTP  200 OK 状态码。

The following ASP.NET Core controller provides an example of handling an event triggered by the Twitter binding:

以下 ASP.NET Core 控制器提供了一个处理 Twitter 绑定触发的事件的示例:

[ApiController]
public class SomeController : ControllerBase
{
    public class TwitterTweet
    {
        [JsonPropertyName("id_str")]
        public string ID {get; set; }

        [JsonPropertyName("text")]
        public string Text {get; set; }
    }

    [HttpPost("/tweet")]
    public ActionResult Post(TwitterTweet tweet)
    {
        // Handle tweet
        Console.WriteLine("Tweet received: {0}: {1}", tweet.ID, tweet.Text);

        // ...

        // Acknowledge message
        return Ok();
    }
}

If the operation should error, you would return the appropriate 400 or 500 level HTTP status code. For bindings that feature at-least-once-delivery guarantees, the Dapr sidecar will retry the trigger. Check out [Dapr documentation for resource bindings][1] to see whether they offer at-least-once or exactly-once delivery guarantees.

如果操作错误,则会返回相应的400或500级别的 HTTP 状态码。 对于 至少传递一次 的绑定保证,Dapr 边车将重试触发。 查看 [有关资源绑定的 Dapr 文档] [1],来查看它们是否提供了 " 至少一次 " 或 "一次性交付 保证"。

Output bindings

输出绑定

Dapr also includes output binding capabilities. They enable your service to trigger an event that invokes an external resource. Again, you start by configuring a binding configuration YAML file that describes the output binding. Once in place, you trigger an event that invokes the bindings API on the Dapr sidecar of your application. Figure 8-3 shows the flow of an output binding:

Dapr 还包括 输出绑定 功能。 它们使服务能够触发调用外部资源的事件。 同样,您首先配置描述输出绑定的绑定配置 YAML 文件。 一旦准备好,可以触发一个事件,该事件在应用程序的 Dapr 边车上调用绑定 API。 图8-3 显示了输出绑定的工作流:

Figure 8-3. Dapr output binding flow.

图 8-3。 Dapr 输出绑定流。

  1. The Dapr sidecar reads the binding configuration file with the information on how to connect to the external resource. In the example, the external resource is a Twilio SMS account.
  2. Your application invokes the /v1.0/bindings/sms endpoint on the Dapr sidecar. In this case, it uses an HTTP POST to invoke the API. It's also possible to use gRPC.
  3. The binding component running in the Dapr sidecar calls the external messaging system to send the message. The message will contain the payload passed in the POST request.
  1. Dapr 边车读取绑定配置文件,其中包含有关如何连接到外部资源的信息。 在此示例中,外部资源是 Twilio 的 SMS 帐户。
  2. 应用程序调用Dapr 边车上的 /v1.0/bindings/sms 终结点。 此处,使用 HTTP POST 来调用 API。 还可以使用 gRPC。
  3. 在 Dapr 边车中运行的绑定组件会调用外部消息系统来发送消息。 消息将包含 POST 请求中传递的负载。

As an example, you can invoke an output binding by invoking the Dapr API using curl:

例如,你可以通过使用curl调用 Dapr API 来调用输出绑定:

curl -X POST http://localhost:3500/v1.0/bindings/sms 
  -H "Content-Type: application/json" 
  -d '{
        "data": "Welcome to this awesome service",
        "metadata": {
          "toNumber": "555-3277"
        },
        "operation": "create"
      }'

Note that the HTTP port is the same as used by the Dapr sidecar (in this case, the default Dapr HTTP port 3500).

请注意,HTTP 端口与 Dapr 边车使用相同的端口 (在本例中为默认 Dapr HTTP 端口3500)  。

The structure of the payload (that is, message sent) will vary per binding. In the example above, the payload contains a data element with a message. Bindings to other types of external resources can be different, especially for the metadata that is sent. Each payload must also contain an operation field, that defines the operation the binding will execute. The above example specifies a create operation that creates the SMS message. Common operations include:

负载 (发送的消息) 的结构将因绑定而异。 在上面的示例中,负载包含 data 元素。 与其他类型的外部资源的绑定可能不同,尤其是元数据metadata 。 每个负载还必须包含一个 operation 字段,该字段定义绑定将执行的操作。 上面的示例指定了 create 操作以创建 SMS 消息。 常见操作包括:

  • create
  • get
  • delete
  • list

It's up to the author of the binding which operations the binding supports. The documentation for each binding describes the available operations and how to invoke them.

取决于绑定支持的操作。 每个绑定的文档描述了可用的操作以及怎样调用。

Using the Dapr .NET SDK

使用 Dapr .NET SDK

The Dapr .NET SDK provides language-specific support for .NET Core developers. In the following example, the call to the HttpClient.PostAsync() is replaced with the DaprClient.InvokeBindingAsync() method. This specialized method simplifies invoking a configured output binding:

Dapr .NET SDK 为 .NET Core 开发人员提供特定于语言的支持。 在下面的示例中,对HttpClient.PostAsync()的调用被替换为对DaprClient.InvokeBindingAsync() 方法的调用。 此专用方法简化了调用已配置的输出绑定:

private async Task SendSMSAsync([FromServices] DaprClient daprClient)
{
    var message = "Welcome to this awesome service";
    var metadata = new Dictionary<string, string>
    {
      { "toNumber", "555-3277" }
    };
    await daprClient.InvokeBindingAsync("sms", "create", message, metadata);
}

The method expects the metadata and message values.

此方法需要 metadata 和 message 值。

When used to invoke a binding, the DaprClient uses gRPC to call the Dapr API on the Dapr sidecar.

当用于调用绑定时,将 DaprClient 使用 gRPC 来调用 Dapr 边车上的 DAPR API。

Binding components

绑定组件

Under the hood, resource bindings are implemented with Dapr binding components. They're contributed by the community and written in Go. If you need to integrate with an external resource for which no Dapr binding exists yet, you can create it yourself. Check out the Dapr components-contrib repo to see how you can contribute a binding.

在后台,资源绑定是通过 Dapr 绑定组件实现的。 它们由社区提供,使用Go开发。 如果需要与还没有 Dapr 绑定的外部资源集成,可以自行创建。 查看 Dapr 组件-contrib 存储库,了解如何参与绑定。

Note

Dapr and all of its components are written in the Golang (Go) language. Go is considered a modern, cloud-native programming platform.

备注

Dapr 及其所有组件都是以 Go 语言编写的。 Go是现代的云本地编程平台。

You configure bindings using a YAML configuration file. Here's an example configuration for the Twitter binding:

使用 YAML 配置文件配置绑定。 下面是用于 Twitter 绑定的示例配置:

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: twitter-mention
  namespace: default
spec:
  type: bindings.twitter
  version: v1
  metadata:
  - name: consumerKey
    value: "****" # twitter api consumer key, required
  - name: consumerSecret
    value: "****" # twitter api consumer secret, required
  - name: accessToken
    value: "****" # twitter api access token, required
  - name: accessSecret
    value: "****" # twitter api access secret, required
  - name: query
    value: "dapr" # your search query, required

Each binding configuration contains a general metadata element with a name and namespace field. Dapr will determine the endpoint to invoke your service based upon the configured name field. In the above example, Dapr will invoke the method annotated with /twitter-mention in your service when an event occurs.

每个绑定配置都包含一个包含 metadata 元素namenamespace 字段。 Dapr 将根据配置的name 字段确定要调用服务的终结点。 在上面的示例中,Dapr 将在事件发生时调用在服务中(使用 /twitter-mention 批注)的方法。

In the spec element, you specify the type of the binding along with binding specific metadata. The example specifies credentials for accessing a Twitter account using its API. The metadata can differ between input and output bindings. For example, to use Twitter as an input binding, you need to specify the text to search for in tweets using the query field. Every time a matching tweet is sent, the Dapr sidecar will invoke the /twitter-mention endpoint on the service. It will also deliver the contents of the tweet.

在 spec 元素中,指定绑定的 type 和绑定特定的 metadata 。 该示例指定了用于访问 Twitter 帐户的凭据,用于将来访问推特的api。 输入绑定和输出绑定的元数据可以不同。 例如,若要使用 Twitter 作为输入绑定,需要使用query 字段指定要在推文中搜索的文本 。 每次发送匹配的推文时,Dapr 边车将调用服务上的 /twitter-mention 终结点。 它还将传递推文的内容。

A binding can be configured for input, output, or both. Interestingly, the binding doesn't explicitly specify input or output configuration. Instead, the direction is inferred by the usage of the binding along with configuration values.

可以将绑定配置为用于输入和/或输出。 有趣的是,绑定未显式指定输入或输出配置。 相反,通过使用绑定以及配置值进行推断方向。

The [Dapr documentation for resource bindings][1] provides a complete list of the available bindings and their specific configuration settings.

[资源绑定的 Dapr 文档] [1] 提供了可用绑定的完整列表及其特定的配置设置。

Cron binding

Cron 绑定

Pay close attention to Dapr's Cron binding. It doesn't subscribe to events from an external system. Instead, this binding uses a configurable interval schedule to trigger your application. The binding provides a simple way to implement a background worker to wake up and do some work at a regular interval, without the need to implement an endless loop with a configurable delay. Here's an example of a Cron binding configuration:

请密切注意 Dapr 的 Cron 绑定。 它不订阅外部系统中的事件。 相反,此绑定使用可配置的间隔计划来触发你的应用程序。 绑定提供了一种简单的途径来实现后台工作线程唤醒,并定期执行一些工作,而无需实现具有可配置延迟的无限循环。 下面是 Cron 绑定配置的示例:

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: checkOrderBacklog
  namespace: default
spec:
  type: bindings.cron
  version: v1
  metadata:
  - name: schedule
    value: "@every 30m"

In this example, Dapr triggers a service by invoking the /checkOrderBacklog endpoint every 30 minutes. There are several patterns available for specifying the schedule value. For more information, see the Cron binding documentation.

在此示例中,Dapr 通过每隔30分钟调用 /checkOrderBacklog 终结点来触发服务。 有多种可用于指定 schedule 值的模式。 有关详细信息,请参阅 Cron 绑定文档

Reference application: eShopOnDapr

参考应用程序: eShopOnDapr

The accompanying eShopOnDapr reference application implements an output binding example. It triggers the Dapr SendGrid binding to send a user an email when a new order is placed. You can find this binding in the eshop-email.yaml file in the components folder:

随附的 eShopOnDapr 参考应用程序实现了输出绑定示例。 它触发 Dapr SendGrid 绑定,以便在有新订单时向用户发送电子邮件。 可以在 components 文件夹的 eshop-email.yaml 文件中找到此绑定:

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: sendmail
  namespace: eshop
spec:
  type: bindings.twilio.sendgrid
  version: v1
  metadata:
  - name: apiKey
    secretKeyRef:
      name: sendGridAPIKey
auth:
  secretStore: eshop-secretstore

This configuration uses the Twilio SendGrid binding component. Note how the API key for connecting to the service consumes a Dapr secret reference. This approach keeps secrets outside of the configuration file. Read the secrets building block chapter to learn more about Dapr secrets.

此配置使用 Twilio SendGrid 绑定组件。 请注意,用于连接到服务的 API 密钥怎样使用 Dapr 机密引用。 此方法在配置文件之外保存机密。 请参阅 机密构建块章节 ,详细了解 Dapr 机密。

The binding configuration specifies a binding component that can be invoked using the /sendmail endpoint on the Dapr sidecar. Here's a code snippet in which an email is sent whenever an order is started:

绑定配置指定一个绑定组件,该组件可使用Dapr 边车上的 /sendmail 终结点进行调用。 以下代码片段将在每次有新订单时发送电子邮件:

public Task Handle(OrderStartedDomainEvent notification, CancellationToken cancellationToken)
{
    var string message = CreateEmailBody(notification);
    var metadata = new Dictionary<string, string>
    {
        {"emailFrom", "eShopOn@dapr.io"},
        {"emailTo", notification.UserName},
        {"subject", $"Your eShopOnDapr order #{notification.Order.Id}"}
    };
    return _daprClient.InvokeBindingAsync("sendmail", "create", message, metadata, cancellationToken);
}

As you can see in this example, message contains the message body. The CreateEmailBody method simply formats a string with the body text. The metadata specifies the email sender, recipient, and the subject for the email message. If these values are static, they can also be included in the metadata fields in the configuration file. The name of the binding to invoke is sendmail and the operation is create.

如本示例中所示, message 包含消息正文。 CreateEmailBody方法只是将字符串转换为正文文本。  metadata 指定电子邮件发件人、收件人和电子邮件的主题。 如果这些值是静态的,则也可以将它们包含在配置文件的元数据字段中。 要调用的绑定的名称为 sendmail ,并且操作为 create 。

Summary

总结

Dapr resource bindings enable you to integrate with different external resources and systems without taking dependencies on their libraries or SDKs. These external systems don't necessarily have to be messaging systems like a service bus or message broker. Bindings also exist for datastores and web resources like Twitter or SendGrid.

Dapr 资源绑定允许你集成不同的外部资源和系统,而无需依赖于这些外部资源和系统的库或 Sdk。 这些外部系统不一定必须是消息传递系统,例如服务总线或消息代理。 数据存储和 web 资源(如 Twitter 或 SendGrid)也可用来绑定。

Input bindings (or triggers) react to events occurring in an external system. They invoke the public HTTP endpoints pre-configured in your application. Dapr uses the name of the binding in the configuration to determine the endpoint to call in your application.

输入绑定 (或触发器) 对外部系统中发生的事件做出响应。 它们调用在你的应用程序中预先配置的公共 HTTP 终结点。 Dapr 使用配置中的绑定名称来确定要在应用程序中调用的终结点。

Output bindings will send messages to an external system. You trigger an output binding by doing an HTTP POST on the /v1.0/bindings/<binding-name> endpoint on the Dapr sidecar. You can also use gRPC to invoke the binding. The .NET SDK offers a InvokeBindingAsync method to invoke Dapr bindings using gRPC.

输出绑定将消息发送到外部系统。 通过在Dapr 边车上的 /v1.0/bindings/<binding-name> 终结点上执行 HTTP POST 来触发输出绑定。 还可以使用 gRPC 来调用绑定。 .NET SDK 提供 InvokeBindingAsync 方法来使用 gRPC 调用 Dapr 绑定。

You implement a binding with a Dapr component. These components are contributed by the community. Each binding component's configuration has metadata that is specific for the external system it abstracts. Also, the commands it supports and the structure of the payload will differ per binding component.

使用 Dapr 组件实现绑定。 这些组件由社区提供。 每个绑定组件的配置都有特定于它所抽象的外部系统的元数据。 此外,它支持的命令和负载的结构将因绑定组件而异。

作者:菜鸟吊思
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
施主您好,贫僧接受供养,施主一粒米,大如须弥山!南无阿弥陀佛!
原文地址:https://www.cnblogs.com/sad-bird/p/14830880.html