1.はじめに
7月にJAZUGが開催した「クラウドデザインパターン勉強会」でお話をさせていただいた「Asynchronous Messaging入門」。11月にはこのリピート&少しだけアップデートのセッションを再度担当させていただきます。
このセッションでService Busのメッセージングで様々な「高信頼メッセージング」をサポートする機能が提供されていることをご紹介しました。
しかし、実際にどんな動きをするのかをイメージしづらかったのではないかと思います。
そこで、次回は様々なメッセージング機能を見ていただけるようなデモを準備しました。
このデモを作成しているうちに「メッセージングの詳細を合わせて説明したい」と強く感じるようになったのですが、時間の関係でそれは叶いません。
そこで、このブログを通じてService Busメッセージングを少し掘り下げて紹介したいと思います。もし「セッションで聞いてみたい」と思われた方がいらっしゃいましたら、フィードバックをお願いいたします。
2.様々な機能は○○Descriptionへ
さて、これまで私自身もサンプルを掲載した際に、「もっとも簡単な方法」でService BusのQueueやTopicを作成してきました。
そこで割愛していたことが今回「もっとも重要な事」になります。
それは、作成時に○○Descriptionのインスタンスを生成し、そこに様々な値を設定して、QueueやTopicそしてSubscriptionの生成時に引数として渡すことです。
QueueであればQueueDescription、TopicであればTopicDescription、SubscriptionであればSubscriptionDescriptionとそれぞれ専用のDescriptionクラスが存在します。
いずれのクラスも類似した値を設定しますが、TopicとSubscriptionは一部のプロパティを振り分けて設定する必要があります。こうした違いを解説していきましょう。
3.まずはQueueから
それでは、最初にQueueDescriptionのプロパティを見ていきましょう。
QueueDescriptionには以下のプロパティが存在します。
名前 | 説明 |
AccessedAt | 前回メッセージが送信された時間、または前回このキューに対する受信要求があった時間を取得します。 |
Authorization | AuthorizationRules を取得します。 |
AutoDeleteOnIdle | キューが自動的に削除されるまでの TimeSpan アイドル間隔を取得または設定します。最小期間は 5 分です。 |
AvailabilityStatus | キューが利用可能かどうかの状態を取得します。 |
CreatedAt | メッセージが作成された時間を取得します。 |
DefaultMessageTimeToLive | メッセージ有効期限の既定値を取得または設定します。これは、メッセージが Service Bus に送信されてから、メッセージの有効期限になるまでの期間です。これは、メッセージ自体で TimeToLive が設定されていない場合の既定値です。TimeToLive の値よりも古いメッセージは有効期限が切れ、メッセージ ストアに保持されなくなります。サブスクライバーは、有効期限が切れたメッセージを受信できません。ここで指定した値よりも低い TimeToLive 値をメッセージに適用することは可能ですが、既定では TimeToLive は MaxValue に設定されています。したがって、このプロパティはメッセージに適用される既定の有効期限値になります。 |
DuplicateDetectionHistoryTimeWindow | 重複データ検出履歴の期間を定義する TimeSpan 構造体を取得または設定します。既定値は 10 分です。 |
EnableBatchedOperations | サーバー側のバッチ操作が有効になっているかどうかを示す値を取得または設定します。 |
EnableDeadLetteringOnMessageExpiration | メッセージの期限が切れたときに、このキューに配信不能のサポートがあるかどうかを示す値を取得または設定します。 |
EnableExpress | エクスプレスエンティティを利用できるようにします。 |
EnablePartitioning | キューを複数のメッセージ ブローカーにわたってパーティション化できるようにします。 |
ExtensionData | 余分なデータを含む構造を取得または設定します。 (EntityDescription から継承されています。) |
ForwardDeadLetteredMessagesTo | 配信不能メッセージの転送先受信者のパスを取得または設定します。 |
ForwardTo | メッセージの転送先受信者のパスを取得または設定します。 |
IsAnonymousAccessible | メッセージに匿名でアクセスできるかどうかを示す値を取得または設定します。 |
IsReadOnly | エンティティの説明が読み取り専用かどうかを示す値を取得または設定します。 (EntityDescription から継承されています。) |
LockDuration | ピーク ロックの期間 (他の受信者に対してメッセージがロックされている期間) を取得または設定します。LockDuration の最大値は 5 分で、既定値は 1 分です。 |
MaxDeliveryCount | 最大の配信数を取得または設定します。この配信数を超えると、メッセージは自動的に配信不能になります。 |
MaxSizeInMegabytes | キューの最大サイズを MB 単位で取得または設定します。これはキューに割り当てられたメモリのサイズです。 |
MessageCount | キューにあるメッセージの数を取得します。 |
MessageCountDetails | キューのメッセージの詳細を取得します。 |
Path | キューの名前を取得します。 |
RequiresDuplicateDetection | このキューで重複データ検出が必要かどうかを示す値を取得または設定します。 |
RequiresSession | キューがセッションの概念をサポートしているかどうかを示す値を取得または設定します。 |
SizeInBytes | キューのサイズをバイト単位で取得します。 |
Status | キューの現在の状態 (有効または無効) を取得または設定します。エンティティが無効になっている場合、そのエンティティはメッセージを送受信できません。 |
SupportOrdering | キューが順序設定をサポートするかどうかを示す値を取得または設定します。 |
UpdatedAt | メッセージが更新された時間を取得します。 |
UserMetadata | ユーザーのメタデータを取得または設定します。 |
出典:MSDNライブラリQueueDescriptionクラス リファレンス
プロパティの一覧を見ただけでこれだけの種類が存在します。
これらの値には、ある値を有効にした場合同時に設定し中ればいけないものの組合せの存在や、排他的に設定されるべき項目が存在します。
そこで、Queueに対して様々な利用シーンを想定した設定の流れを紹介してみたいと思います。
4.重複メッセージの検知を有効にする
重複メッセージの検知を有効にする場合、RequiresDuplicateDetectionプロパティ値をtrueに指定します。これにより重複メッセージを自動的に除去することが可能です。なお、重複メッセージを検知するために一定期間メッセージを保管する必要があるため、メッセージを保管する期間をDuplicateDetectionHistoryTimeWindowプロパティにTimeSpan型で指定します。リファレンスにもある通り、デフォルトは10分です。
ここで、注意する必要がある点はエクスプレスエンティティと重複メッセージ検知を同時に有効化できない点です。エクスプレスエンティティはごく短い保存期間の間にメッセージが読みだされることを想定して設定するものであり、メッセージは一旦メモリ上に保管されます。そのため、永続化領域に一旦メッセージをセーブする必要のある重複メッセージ検知と併用できないのです。同時に有効化した場合、Queueの作成時にInvalidOperationExceptionがスローされます。
以下に、重複メッセージ検知を有効にするためにコードスニペットを記載します。
string connectionString = “サービス バス接続文字列に置き換える”;
string QueueName = “myQueue”;
//NameSpaceManagerを作成
NamespaceManager namespaceManager
= NamespaceManager.CreateFromConnectionString(connectionString);
//同一名称キューの存在をチェックし、重複時は強制的に既存キューを削除
if (namespaceManager.QueueExists(QueueName))
namespaceManager.DeleteQueue(QueueName);
QueueDescription queueDescription
= new QueueDescription(QueueName);
//重複メッセージ除去
queueDescription.RequiresDuplicateDetection = true;
//重複メッセージ履歴保存時間(15秒に指定)
queueDescription.DuplicateDetectionHistoryTimeWindow
= TimeSpan.FromMinutes(15);
namespaceManager.CreateQueue(queueDescription);
上記の例では、重複メッセージ検知のために15分間メッセージを保管します。この場合、保管期間内に同一のメッセージIDを持つメッセージが重複してQueueにポストされた場合、重複するメッセージは自動的に削除されます。
ここで注意が必要な点は、メッセージの重複を検知するためにIDのチェックを実施しますが本文はチェックされないことです。そのため、本文内容は異なるもののメッセージIDが同一である場合は重複とみなされます。したがって、メッセージには必ず固有のIDを付与するようにしなければなりません。
5.配信不能メッセージの除去
メッセージ内容が不正である場合など、ある理由でメッセージの処理が続行できない様な場合、そのメッセージの存在が原因となり以降のメッセージ処理が停止してしまうことが想定されます。Service Bus Queueではこうした不正なメッセージ(ポイズンメッセージ)を一定のルールに基づき配信不能キューに移動することが可能です。
この機能を有効にするにはEnableDeadLetteringOnMessageExpirationプロパティにtrueを設定します。同時にForwardDeadLetteredMessagesToプロパティに配信不能キューの名称を指定します。この時、ForwardDeadLetteredMessagesToで指定された名称のQueueが名前空間内に存在している必要があります。存在しない名前のキューを指定した場合、Queue作成時に例外が発生します。また、リトライする最大回数をMaxDeliveryCountプロパティに指定します。以下に、配信不能メッセージを自動転送するためのコードスニペットを記載します。
//最大配信回数(10回に指定)
queueDescription.MaxDeliveryCount = 10;
//配信不能キュー利用
queueDescription.EnableDeadLetteringOnMessageExpiration = true;
//配信不能キュー名称
queueDescription.ForwardDeadLetteredMessagesTo = “deadletterqueue”;
~・~・~・~・~・~・~・~・~・~・~・~・~・~・~・~・~・~・~・~・
今回は2つの機能有効化の例をご紹介しました。今後、他の高信頼メッセージング機能の利用法も継続してご紹介していきます。
次回は、バッチ受信、セッション有効化、順序性サポート、メッセージ有効期限設定を取り上げたいと思います。
Comments are closed here.