什么是系結
處理外部事件或呼叫外部介面的功能就是系結,系結可以提供以下好處:
- 避免連接到訊息系統 ( 如佇列和訊息總線 ) 并進行輪詢的復雜性
- 聚焦于業務邏輯,而不是如何與系統互動
- 使代碼不受 SDK 或外部庫的強耦合
- 處理重試和故障恢復
Dapr提供了很多支持的系結,請見系結,系結分為輸入系結與輸出系結,輸入系結是監聽外部事件,觸發業務邏輯,輸出系結是呼叫外部資源,
系結可能與前面介紹的發布訂閱類似, 盡管它們很相似,但也有不同之處, 發布/訂閱側重于 Dapr services 之間的異步通信, 資源系結具有更大的范圍, 它側重于軟體平臺之間的系統互操作性, 在不同的應用程式、資料存盤和微服務應用程式之外的服務之間交換資訊,
作業原理
Dapr 資源系結需要通過yaml檔案定義系結組件, 此 YAML 檔案描述要與其系結的資源型別, 配置后,你的服務可以接收來自資源的事件或觸發事件,
輸入系結
輸入系結通過外部資源的傳入事件觸發代碼, 下圖的示例中需要在app中保留/tweet介面,以供sidecar呼叫

- Dapr Sidecar讀取系結組態檔并訂閱為外部資源,
- 當外部資源觸發時,在 Dapr sidecar中運行的系結組件會選取它并觸發一個事件,
- Dapr sidecar呼叫指定的介面, 在此示例中,服務在
/tweet埠6000上偵聽終結點上的 HTTP POST, 由于它是 HTTP POST 操作,因此在請求正文中傳遞事件的 JSON 有效負載, - 處理事件后,服務將回傳 HTTP 狀態代碼
200 OK,
輸出系結
輸出系結使服務能夠觸發呼叫外部資源, 跟輸入系結同樣,需要配置描述輸出系結的系結配置 YAML 檔案,該事件在應用程式的 Dapr Sidecar上呼叫bingdings API,

- Dapr sidecar讀取系結組態檔,其中包含有關如何連接到外部資源的資訊,
- 應用程式呼叫sidecar的
/v1.0/bindings/smsDapr 終結點, 在這種情況下,它使用 HTTP POST 來呼叫 API, 還可以使用 gRPC, - Dapr sidecar的系結組件會呼叫外部訊息系統來發送訊息, 訊息將包含 POST 請求中傳遞的負載,
專案實體
此例子中我們使用rabbitmq作為外部資源,因為rabbitmq既支持輸入系結又支持輸出系結,
首先,在默認組件目錄C:\Users\<username>\.dapr\components中新建rabbitbinding.yaml
apiVersion: dapr.io/v1alpha1 kind: Component metadata: name: RabbitBinding spec: type: bindings.rabbitmq version: v1 metadata: - name: queueName value: queue1 - name: host value: amqp://admin:[email protected]:5672 - name: durable value: true - name: deleteWhenUnused value: false - name: ttlInSeconds value: 60 - name: prefetchCount value: 0 - name: exclusive value: false - name: maxPriority value: 5
每個系結配置都在metadata 中包含常規元素 name 和 namespace , Dapr 將根據配置的 name 欄位確定要呼叫的服務的終結點 , 在上面的示例中,Dapr 將在事件發生是呼叫 /RabbitBinding 事件發生時呼叫方法,
我們在FrontEnd中定義RabbitBindingController
using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using System.IO; using System.Text; namespace FrontEnd.Controllers { [Route("[controller]")] [ApiController] public class RabbitBindingController : ControllerBase { private readonly ILogger<RabbitBindingController> _logger; public RabbitBindingController(ILogger<RabbitBindingController> logger) { _logger = logger; } [HttpPost] public ActionResult Post() { Stream stream = Request.Body; byte[] buffer = new byte[Request.ContentLength.Value]; stream.Position = 0L; stream.ReadAsync(buffer, 0, buffer.Length); string content = Encoding.UTF8.GetString(buffer); _logger.LogInformation(".............binding............." + content); return Ok(); } } }
現在我們啟動Frontend程式
https://docs.dapr.io/zh-hans/reference/components-reference/supported-bindings/rabbitmq/
然后打開RabbitMQ Management,查看Queue,發現queue1已成功創建

我們先來驗證輸入系結,在RabbitMQ Management中直接發送訊息

現在去控制臺查看日志,發現輸入系結成功觸發
== APP == info: FrontEnd.Controllers.RabbitBindingController[0] == APP == .............binding.............1111111122222
現在我們來驗證輸出系結,在RabbitBindingController中新建介面
[HttpGet] public async Task<ActionResult> GetAsync([FromServices]DaprClient daprClient) { await daprClient.InvokeBindingAsync("RabbitBinding", "create", "9999999"); return Ok(); }
為了防止新建的訊息被輸入系結消費,先把Post方式注釋掉
//[HttpPost] //public ActionResult Post() //{ // Stream stream = Request.Body; // byte[] buffer = new byte[Request.ContentLength.Value]; // stream.Position = 0L; // stream.ReadAsync(buffer, 0, buffer.Length); // string content = Encoding.UTF8.GetString(buffer); // _logger.LogInformation(".............binding............." + content); // return Ok(); //}
現在呼叫, 查看佇列queue1中的訊息,可看到剛才輸出的消息
http://localhost:3501/v1.0/invoke/frontend/method/RabbitBinding

查看結果

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/308044.html
標籤:.NET Core
