次の方法で共有


Azure Event Grid でのクライアント側フェールオーバーの実装

ディザスター リカバリーには、通常、リージョンが異常になったときの中断を防ぐためのバックアップ リソースの作成が含まれます。 このプロセス中は、ワークロードに Azure Event Grid リソースのプライマリとセカンダリのリージョンが必要になります。

アプリケーション機能の重大な損失から復旧するには、さまざまな方法があります。 この記事では、異常なリソースまたはリージョンが原因で障害から回復するようにクライアントを準備するために従う必要があるチェックリストについて説明します。

Event Grid では、サーバー側で手動および自動 geo ディザスター リカバリー (GeoDR) がサポートされます。 フェールオーバー プロセスをさらに細かく制御したい場合には、クライアント側のディザスター リカバリー ロジックを実装することもできます。 自動 GeoDR の詳細については、「Server-side geo disaster recovery in Azure Event Grid (Azure Event Grid 内のサーバー側 geo ディザスター リカバリー)」を参照してください。

Event Grid でのクライアント側フェールオーバーと geo ディザスター リカバリーのサポートを次の表に示します。

Event Grid リソース クライアント側フェールオーバーのサポート geo ディザスター リカバリー (GeoDR) のサポート
カスタム トピック サポートされています 地域をまたがる/地域内
システム トピック サポートされていません 自動的に有効化
ドメイン サポートされています 地域をまたがる/地域内
パートナー名前空間 サポートされています サポートされていません
名前空間 サポートされています サポートされていません

クライアント側のフェールオーバーに関する考慮事項

  1. プライマリ Event Grid リソースを作成して構成します。
  2. セカンダリ Event Grid リソースを作成して構成します。
  3. 両方のリソースで同じ構成、サブリソース、および機能が有効になっている必要があることに注意してください。
  4. Event Grid リソースは、異なるリージョンでホストする必要があります。
  5. Event Grid リソースに配信不能のストレージ リソースなどの依存リソースがある場合は、セカンダリ Event Grid リソースで使用されるのと同じリージョンを使用する必要があります。
  6. 復旧計画リソースが適切に配置され、正常に機能していることを保証するために、エンドポイントが定期的にテストされていることを確認します。

カスタム トピックの基本的なクライアント側フェールオーバー実装サンプル

次のサンプル コードは、最初にプライマリ トピックに発行しようとする単純な .NET 発行元です。 成功しない場合は、セカンダリ トピックをフェールオーバーします。 どちらの場合も、 https://<topic-name>.<topic-region>.eventgrid.azure.net/api/healthで GET を実行して、他のトピックの正常性 API もチェックします。 /api/health エンドポイントで GET が作成されると、正常なトピックは常に 200 OK で応答する必要があります。

次のサンプル コードはデモンストレーションのみを目的としており、運用環境での使用を目的としたものではありません。

using System;
using System.Net.Http;
using System.Collections.Generic;
using System.Threading.Tasks;
using Azure;
using Azure.Messaging.EventGrid;

namespace EventGridFailoverPublisher
{
    // This captures the "Data" portion of an EventGridEvent on a custom topic
    class FailoverEventData
    {
        public string TestStatus { get; set; }
    }

    class Program
    {
        static async Task Main(string[] args)
        {
            // TODO: Enter the endpoint each topic. You can find this topic endpoint value
            // in the "Overview" section in the "Event Grid topics" page in Azure Portal..
            string primaryTopic = "https://<primary-topic-name>.<primary-topic-region>.eventgrid.azure.net/api/events";
            string secondaryTopic = "https://<secondary-topic-name>.<secondary-topic-region>.eventgrid.azure.net/api/events";

            // TODO: Enter topic key for each topic. You can find this in the "Access Keys" section in the
            // "Event Grid topics" page in Azure Portal.
            string primaryTopicKey = "<your-primary-topic-key>";
            string secondaryTopicKey = "<your-secondary-topic-key>";

            Uri primaryTopicUri = new Uri(primaryTopic);
            Uri secondaryTopicUri = new Uri(secondaryTopic);

            Uri primaryTopicHealthProbe = new Uri($"https://{primaryTopicUri.Host}/api/health");
            Uri secondaryTopicHealthProbe = new Uri($"https://{secondaryTopicUri.Host}/api/health");

            var httpClient = new HttpClient();

            try
            {
                var client = new EventGridPublisherClient(primaryTopicUri, new AzureKeyCredential(primaryTopicKey));

                await client.SendEventsAsync(GetEventsList());
                Console.Write("Published events to primary Event Grid topic.");

                HttpResponseMessage health = httpClient.GetAsync(secondaryTopicHealthProbe).Result;
                Console.Write("\n\nSecondary Topic health " + health);
            }
            catch (RequestFailedException ex)
            {
                var client = new EventGridPublisherClient(secondaryTopicUri, new AzureKeyCredential(secondaryTopicKey));

                await client.SendEventsAsync(GetEventsList());
                Console.Write("Published events to secondary Event Grid topic. Reason for primary topic failure:\n\n" + ex);

                HttpResponseMessage health = await httpClient.GetAsync(primaryTopicHealthProbe);
                Console.WriteLine($"Primary Topic health {health}");
            }

            Console.ReadLine();
        }

        static IList<EventGridEvent> GetEventsList()
        {
            List<EventGridEvent> eventsList = new List<EventGridEvent>();

            for (int i = 0; i < 5; i++)
            {
                eventsList.Add(new EventGridEvent(
                    subject: "test" + i,
                    eventType: "Contoso.Failover.Test",
                    dataVersion: "2.0",
                    data: new FailoverEventData
                    {
                        TestStatus = "success"
                    }));
            }

            return eventsList;
        }
    }
}

試してみる

すべてのコンポーネントが配置されたので、フェールオーバーの実装をテストできます。

フェールオーバーが機能していることを確認するために、プライマリ トピック キーの一部の文字を変更して無効にすることができます。 パブリッシャーをもう一度実行してみてください。 次のサンプル イベントは引き続き Event Grid を通過しますが、クライアントを見ると、セカンダリ トピックを介して発行されていることがわかります。

拡張の可能性

ニーズに基づいてこのサンプルを拡張する方法は多数あります。 大量のシナリオでは、トピックの正常性 API を個別に定期的に確認することをお勧めします。 そうすれば、トピックがダウンした場合は、発行ごとにチェックする必要はありません。 トピックが正常でないことがわかっている場合は、既定でセカンダリ トピックに発行できます。

同様に、特定のニーズに基づいてフェールバック ロジックを実装することもできます。 待機時間を短縮するために最も近いデータ センターに発行することが重要な場合は、フェールオーバーされたトピックの正常性 API を定期的にプローブできます。 もう一度正常になったら、近くのデータ センターにフェールバックしても安全です。

次のステップ