2018 年 9 月

第 33 卷 9

本文章是由機器翻譯。

Azure-管理使用 Azure 事件格線的事件傳遞

藉由David Barkol

Event Grid 是完全受控的傳訊服務於 Microsoft Azure 的路由事件在雲端中及更新版本提供創新的方法。已新增的解除鎖定和如何事件導向解決方案的唯一模式設計與功能強大且彈性的發佈-訂閱模型。

我提供在 2018 年 2 月期 Azure Event Grid 簡介 (aka.ms/eventgridarticle),探索服務以及如何使用它來發佈和取用事件,以各種方式的基本概念。在這個新的文章中,我會深入探討如何傳遞事件和選項會重試原則、 無效的事件和不成功傳遞的事件。我深入探討之前,它會透過 Event Grid 高的層級的運作方式幫助。

Event Grid 的簡要概觀

使用 Azure Event Grid,事件來源可能來自持續增加在 Azure 中,例如事件中樞和媒體服務中,或甚至是從內部部署執行的自訂應用程式或其他雲端提供者或資料中心內的服務清單。這些事件已取用,且受到 Event Grid,負責擷取的訊息,並以其散發給每個事件訂用帳戶。事件處理常式用來處理內送事件,而且可以在 Azure 中的服務。非常受歡迎的案例是利用其他的無伺服器技術,例如 Functions 和 Logic Apps。在一起,這些可高度擴充且彈性的解決方案可以包含非常快速且實惠的方式而不需要管理任何基礎結構的負擔。

事件處理常式也可以是簡單的 WebHook,就像事件來源,這表示它可以位於任何地方,只要它支援 HTTPS,而且可以接受 POST 要求。此平台和語言無關的方法是讓事件格線非常特殊的服務,以開啟 [設定在雲端中的新解決方案才剛開始的許多選項。[圖 1說明如何使用 Event Grid,以連接多個來源和處理常式。在 Azure 中使用 Event Grid 整合的服務清單會不斷成長,只有部分所示的圖表。

Azure Event Grid 概觀
[圖 1 Azure Event Grid 概觀

事件傳遞和回應碼

Event Grid 會獨立地將每個事件。這表示沒有固定的順序的事件,在某些情況下,事件可以一次以上傳遞。因此,它是事件處理常式,並謹慎撰寫程式碼具有等冪性的責任。重複傳送相同的事件應該會產生相同的結果。如果事件的順序是需求,這應該管理任一邊計算 (在事件處理常式的邏輯) 或使用另一個服務,例如服務匯流排或事件中樞保留它們的順序。

Event grid 的事件處理常式所傳回的 HTTP 回應將會決定如何繼續與管理的事件。狀態碼 200 OK 」 和 「 202 已接受會被視為成功傳遞事件的通知。

任何下列的失敗碼較長的傳遞失敗的嘗試:400 不正確的要求,401 未經授權,404 找不到,408 要求逾時,414 URI 太長,500 內部伺服器錯誤 」、 「 503 服務無法使用與 「 504 閘道逾時。根據失敗的程式碼,Event Grid 可能會重試將事件傳送至端點。我會深入探究這只是有點。

重試原則

如果未收到通知,或在傳回的錯誤碼,另一個將會嘗試將事件傳送至端點。重試原則會採用指數的備份,然後放入嘗試事件到期前的最後一個傳遞的地方。根據預設,事件的成功傳遞的 24 小時後到期。第一次嘗試之後,傳遞排程將會回復,使用下列時間軸:10 秒時,30 秒,1 分鐘、 5 分鐘、 30 分鐘到 1 小時 10 分鐘。在第一次嘗試一小時之後, 每個後續的要求會一次每小時的存留時間 (TTL) 為止。

Event Grid 中的新功能可讓您設定兩個可能的值來設定事件訂閱的重試原則:

最大傳遞嘗試是一個可設定的值,設定最大重試嘗試次數,事件訂用帳戶。其預設值,以及允許的最大值為 30。

事件 TTL 是對應到事件的存留時間設定的值。其預設值,以及其最大值的設定,為 1,440 分鐘 (24 小時)。

可能是這些屬性可用來管理重試原則,在事件訂用帳戶層級和事件有趣的是您只會針對一段時間,或您以保護您自己在高 loa 期間刻意擲回例如 503 錯誤時很有用d。

無效,且無作用的字母通道

其中一個訊息服務的主要責任是為了確保正確地傳遞訊息。不過,它無法保證,該訊息的接收者會處理它成功。

在某些情況下,如果它不符合預期的事件接收器時,可能會拒絕該訊息。這可能有無效的資料類型或內容或未經授權的訊息的格式。當發生這種情況時,訊息通常會移到指定的位置,通常稱為 「 無效的訊息的通道。

另一個常見案例是成功傳送,但由於 [接收端上發生錯誤而無法處理的訊息。這些通常是因為服務發生錯誤或是服務無法使用的 500 層級狀態碼。通常,傳訊服務會重試傳送這些訊息,直到符合臨界值,而且訊息被視為無法傳遞。寄不出信件 channelis,類似於無效的訊息通道,以儲存這些訊息,以及任何相關的中繼資料。

在這兩種案例的需求是,將會有一些公用程式或服務,通道會監視並知道該如何處理訊息。這可能呈現在排定的報表或其他事件導向的服務,例如邏輯應用程式,可以取用訊息,並通知使用者或其他系統和服務。

使用 Event Grid 的無法傳送信件訊息

高要求的功能適用於 Azure Event Grid 短時間內釋出之後是提供的機制來擷取無法傳遞的事件。這項功能具有最近隨附威力在於讓您設定的重試原則和每個事件訂用帳戶的寄不出信件位置。使用此功能,我現在可以設定的訊息和其傳遞的相關詳細資料會擷取 Azure 儲存體帳戶的寄不出信件通道。這個相同的端點將做為寄不出信件 」 和 「 無效的訊息的通道。[圖 2說明如何寄不出信件事件現在支援 Azure Event Grid 中。

寄不出信件事件
[圖 2 寄不出信件事件

我想特別提出幾個重要的詳細資訊,再將範例放在一起使用的重試原則 」 和 「 寄不出信件傳遞。

請注意,來自 Event Grid 主題的箭號將處理常式的方向。我想要這一點要強調的 Event Grid 是推播推送模型的概念。事件處理常式提供來傳送事件的時候,Event Grid 所呼叫的 webhook。這項重要的設計決策強調的是服務的事件導向本質。不同於其他傳訊服務,就不再需要求助於長時間輪詢 」 或 「 hammer 輪詢的技術,以檢查是否有可用的訊息。相反地,處理常式可以依賴此模型,即可收到新事件,這是另一個事件處理常式函式和 Logic Apps 等無伺服器技術為何吸引人的原因。讓我們將此做法。

設定

現在我將引導您完成安裝和設定的重試原則和寄不出信件端點的步驟。此外,它有多好也檢查寄不出信件事件,並立即在它們變成可用之後,對它們做出回應。

我要在 Azure 中設定的所有項目會從 Azure Cloud Shell 中執行。這可確保您可以從任何電腦,並不是任何特定的工具或其他相依性的掌控。關於 Azure Cloud Shell 的詳細資訊,請參閱bit.ly/2CsFtQB

在撰寫本文時,這項功能處於預覽狀態,或雖然很有可能會釋放,才能發行後不久。雖然在預覽中,您必須安裝在命令列介面 (CLI) 中使用它的 Event Grid 延伸模組:

az extension add -–name eventgrid

簡潔,我將會在練習重複使用的幾個區域變數:

rgname=msdndemo
topicname=<your-unique-grid-topic-name>
storagename=<your-unique-storage-account-name>
containername=deadletterevents

我要建立資源群組、 儲存體帳戶和容器,用以接收寄不出信件的事件,如中所示**[圖 3**。

[圖 3 建立的資源群組、 儲存體帳戶和容器

# create resource group
az group create --name $rgname -l westus2
# create storage account
az storage account create \
  -–name $storagename \
  --location westus2 \
  --resource-group $rgname \
  --sku Standard_LRS \
  --kind StorageV2 \
  --access-tier Hot
# create storage container
export AZURE_STORAGE_ACCOUNT=$storagename
export AZURE_STORAGE_ACCESS_KEY=”$(az storage account keys list -–account-name $storagename
  --resource-group $rgname –-query “[0].value” –-output tsv)”
az storage container create –-name $containername

接下來,我需要儲存體帳戶的資源識別碼。這將用於,容器名稱,以及定義寄不出信件端點:

# storage ID
storageid=$(az storage account show –-name $storagename
  –-resource-group $rgname –-query id --output tsv)  
# container ID for dead letter channel
containerid="$storageid/blobservices/default/containers/$containername"

我將傳送事件至自訂的 Event Grid 主題。讓我們來建立主題,並儲存端點位址和存取金鑰。發佈事件時,將會稍後利用這些值:

# create custom topic
az eventgrid topic create -g $rgname –-name $topicname -l westus2
# save topic endpoint
topicendpoint=$(az eventgrid topic show –-name $topicname -g $rgname
  –-query “endpoint” –-output tsv) 
# save topic key
topickey=$(az eventgrid topic key list --name $topicname -g $rgname
  --query "key1" --output tsv)

Azure Functions 事件處理常式

在此案例中,我將假設使用者,將歌曲要求傳送至專精於藍調音樂的虛構的廣播電台。要求會在中,它們是將它放入電台播放清單。不過,如果歌曲的內容類型不符合目標音樂的廣播電台,它將會遭到拒絕,而且放在寄不出信件通道上。

事件處理常式是在第 2 版執行階段上建置 Azure 函式。它會檢查事件的 [主旨] 欄位,核准或據以拒絕歌曲要求。在 Azure 函式程式碼所示**[圖 4**。

圖 4] 的 Azure 函式的事件處理常式

using System.IO;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Azure.EventGrid.Models;
using Microsoft.Azure.WebJobs.Host;
using Newtonsoft.Json;
using Microsoft.Extensions.Logging; 

namespace WeWantTheFunc
{
  public static class SongRequestHandler
  {
    [FunctionName("SongRequestHandler")]
    public static IActionResult Run(
      [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]
      HttpRequest req, ILogger log)
    {
      // Get the body of the request
      var requestBody = new StreamReader(req.Body).ReadToEnd();
      // Check the header for the event type           
      if (!req.Headers.TryGetValue("Aeg-Event-Type", out var headerValues))
        return new BadRequestObjectResult("Not a valid request");
      var eventTypeHeaderValue = headerValues.FirstOrDefault();
      if (eventTypeHeaderValue == "SubscriptionValidation")
      {
        // Validate the subscription
        var events = JsonConvert.DeserializeObject<EventGridEvent[]>(requestBody);
        dynamic data = events[0].Data;
        var validationCode = data["validationCode"];
        return new JsonResult(new
        {
          validationResponse = validationCode
        });
      }
      else if (eventTypeHeaderValue == "Notification")
      {
        // Handle the song request
        log.LogInformation(requestBody);
        var events = JsonConvert.DeserializeObject<EventGridEvent[]>(requestBody);
        // Reject the request if it does not
        // match the genre for the station.
        if (events[0].Subject != "genre/blues")
          return new BadRequestObjectResult("Sorry, this is a Blues station");
        return new OkObjectResult("");
      }
      return new BadRequestObjectResult("Not a valid request");
    }
  }
}

此函式有兩個部分。若要查看供傳入事件驗證端點會先檢查。如果是驗證要求,則函數會傳回證明擁有權並接受內送訊息的驗證程式碼。

函式的第二個部分是來自 Event Grid 的事件通知。傳回不正確的要求回應 (401),將不會再將事件傳送至處理常式進行明確的陳述式。這把話題帶到程序的最重要的部分-建立事件訂用帳戶。

訂閱事件

所有項目就地,終於建立示範的重試原則 」 和 「 寄不出的信件功能的事件訂用帳戶。假設是中的 Azure 函式**[圖 4**已部署,而且目前正在 Azure 中執行。建立訂用帳戶的命令如下所示:

az eventgrid event-subscription create \
  --endpoint <your-azure-function-url> \
  --topic-name $topicname \
  -g $rgname \
  --name song-request-sub \
  --deadletter-endpoint $containerid \
  --max-delivery-attempts 2
  --event-ttl 1

請注意,將 [最大傳遞嘗試] 與 [事件 ttl 設定會包含在內。不需要包含兩個設定,但他們若要設定的重試原則可以一起使用。我要將傳遞嘗試次數上限設定為兩個與存留時間為一分鐘。另一個新的引數,稱為寄不出信件端點會初始化為使用變數稍早建立的儲存體帳戶容器。它會傳送一些事件,並查看此工作端對端的時間。

傳送事件

從 CLI 中,我可以複製包含歌曲要求的範例主體。此要求會實際包含的事件處理常式將會拒絕無效的音樂內容類型 (Rock)。

# copy the request body
body=$(eval echo "'$(curl https://raw.githubusercontent.com/dbarkol/azure-event-grid-patterns/master/badsongrequest.json)'")
# post the request to the custom topic endpoint
curl -X POST -H "aeg-sas-key: $topickey" -d "$body" $topicendpoint

在預期情況是,幾分鐘後傳送訊息,它最後會當做寄不出信件通道設定的儲存體帳戶容器。若要查看每個成為無效信件訊息建立新的 blob,您可以使用 Azure 儲存體總管之類的工具。不過,其實沒有非常令人興奮。另外,我想要在新的訊息新增至寄不出信件通道時收到通知。

檢查寄不出信件事件

因為寄不出信件事件只是在容器中建立的新 blob 時,Event Grid 可用來開始進行另一個檔案建立時觸發的工作流程。[圖 5示範工作流程,如何事件可以來自於儲存體帳戶和最終由邏輯應用程式接收和傳送電子郵件。

Logic Apps 所處理的 blob 事件
[圖 5 Blob 事件,由邏輯應用程式

唯一要匯集是開始使用 Event Grid 觸發程序的邏輯應用程式。應用程式中的前三個步驟包含下列動作和觸發程序:

事件格線觸發程序已針對儲存體帳戶。它會使用兩個篩選條件,一個用於事件類型 (Microsoft.Storage.BlobCreated),第二個容器使用的前置詞篩選選項。這些篩選器都可以確保應用程式才叫用時專用的寄不出信件容器內建立新的檔案。

初始化變數是從 Event Grid 訊息的主體擷取 URL 的下一個動作。其值為下列運算式:

triggerBody()?['data']['url']

取得 blob 的內容使用的路徑是將讀取的 blob 內容的動作。若要移除的部分,則不需要使用此字串操作運算式的 blob 路徑的值格式化我:

replace(variables('DeadLetterUrl'),
  'https://<storage-account-name>.blob.core.windows.net', '')

這些初始步驟所示**[圖 6**。

事件格線觸發邏輯應用程式
[圖 6 事件格線觸發邏輯應用程式

以下是邏輯應用程式的最後一個動作:

剖析 JSON 會評估 blob 的內容,並提供一組變數,我可以在稍後參考。內容屬性的運算式為:

json(body('Get_blob_content_using_path'))

我還需要提供的範例承載看起來像:

[{
  "id":"100",
  "eventTime":"2017-08-21T06:42:20.0000000+00:00",
  "eventType":"type",
  "dataVersion":"",
  "metadataVersion":"1",
  "topic":"enpoint",
  "subject":"testsubject",
  "deadLetterReason":"reason",
  "deliveryAttempts":1,
  "lastDeliveryOutcome":"BadRequest",
  "lastHttpStatusCode":400,
  "data":{"something":"data"}
}]

傳送電子郵件格式的主體和事件 (寄不出信件原因和主體) 的成品與電子郵件的主旨,最後一個動作。因為裝載實際上包含的陣列,Logic Apps 會辨識,並將包裝中的動作的每個動作。

附帶一提,每個步驟內的每個迴圈會平行完成而不是循序 Logic Apps 中;這是可視需要循序執行,可以變更預設行為。最後的結果會顯示在**[圖 7**。

剖析 JSON 及傳送通知
[圖 7 剖析 JSON 及傳送通知

測試此端對端,將會導致每一個寄不出信件事件傳送一封電子郵件。

總結

與其原始的設計和有越來越多的 Azure 服務密切整合,Event Grid 只會顯示創新的方式,來建置事件驅動的解決方案開始。在本文中,我示範了如何運用新的重試原則及 dead lettering Azure Event Grid 中的功能。這些期待的功能是功能強大的選項,進行更彈性且可擴充的 Event Grid 上建置的解決方案。這篇文章中的程式碼,請參閱bit.ly/2LGKjhN


David Barkol是通用的 「 黑帶 」 小組的 microsoft Azure 專家。您可以連絡他的 Twitter: @dbarkol或透過電子郵件dabarkol@microsoft.com。定期關於 Event Grid,在他的部落格madeofstrings.com

感謝下列 Microsoft 技術專家來檢閱這篇文章:Bahram Banisadr

Bahram Banisadr 是負責建置連結個生物組織的 Azure 服務運作的 Azure Event Grid PM。


MSDN Magazine 論壇中的這篇文章的討論