Service Bus メッセージングの例外 (.NET)
サービス操作またはクライアントでエラーが発生すると、Service Bus .NET クライアント ライブラリは例外を提示します。 可能な場合は、.NET の標準の例外の種類を使ってエラー情報が伝えられます。 Service Bus に固有のシナリオでは、ServiceBusException がスローされます。
例外が一時的と見なされる場合、Service Bus クライアントは、構成されている再試行オプションに従って自動的に再試行します。 例外がアプリケーションに提示されるのは、適用されたすべての再試行が失敗したときか、例外が一時的ではないと見なされたときです。 再試行オプションの構成について詳しくは、「再試行オプションのカスタマイズ」のサンプルをご覧ください。
ServiceBusException
例外には、エラーのコンテキストとその相対的な重大度を理解するのに役立つ、コンテキスト情報が含まれています。
EntityPath
: わかる場合、例外が発生した Service Bus エンティティを示します。IsTransient
: 例外が回復可能と見なされるかどうかを示します。 一時的であると見なされた場合は、Azure Service Bus で適切な再試行ポリシーが既に適用されており、すべての再試行が失敗しました。Message
: 発生したエラーと関連するコンテキストの説明を提供します。StackTrace
: 呼び出し履歴の直前のフレームを表し、エラーが発生したコード内の場所を明示します。InnerException
: 例外がサービス操作の結果であったときは、多くの場合、OASIS Advanced Message Queuing Protocol (AMQP) 1.0 の仕様に従ってエラーを記述するMicrosoft.Azure.Amqp.AmqpException
インスタンスです。Reason
: 根本原因の分類と明確化に役立つ、エラーに関する一連の既知の原因を示します。 これらの値は、例外メッセージのテキストを調べることが理想的ではない場合に、例外のフィルター処理やその他のロジックを適用できるようにするためのものです。 障害の主な理由をいくつか次に示します。ServiceTimeout
: 予想される時間内に、Service Bus サービスが操作要求に応答しなかったことを示します。 これは、一時的なネットワークの問題またはサービスの問題によるものである可能性があります。 Service Bus サービスは要求を正常に完了した可能性も、しなかった可能性もあり、状態は不明です。 次に使用可能なセッションのコンテキストでは、この例外は、エンティティにロック解除された使用可能なセッションがなかったことを示します。 これらのエラーは、自動的に再試行される一時的なエラーです。QuotaExceeded
: 通常、アクティブな受信操作が 1 つのエンティティに対しては多すぎることを示します。 このエラーを回避するには、可能性のある同時受信の数を減らします。 バッチ受信を使って、受信要求ごとに複数のメッセージの受信を試みることができます。 詳しくは、「Service Bus のクォータ」をご覧ください。MessageSizeExceeded
: メッセージのサイズがメッセージの最大サイズを超えたことを示します。 メッセージのサイズには、メッセージの本文と、関連付けられているメタデータが含まれます。 このエラーを解決するための最善の方法は、バッチで送信されるメッセージの数、またはメッセージに含まれる本文のサイズを減らすことです。 サイズ制限は変更される可能性があるため、詳しくは「Service Bus のクォータ」をご覧ください。MessageLockLost
: メッセージに対するロックが失われることを示します。 呼び出し元は、メッセージの受信と処理をもう一度試みる必要があります。 この例外は、セッションを使用しないエンティティにのみ適用されます。 このエラーは、処理にロック期間より長い時間がかかり、メッセージ ロックが更新されない場合に発生します。 このエラーは、一時的なネットワークの問題が原因でリンクがデタッチされるときや、リンクが 10 分間アイドル状態になっているときにも、発生する可能性があります。Service Bus サービスでは、ステートフルな AMQP プロトコルが使われます。 このプロトコルの性質上、メッセージが受信されてから解決されるまでの間に、クライアントとサービスを接続するリンクがデタッチされた場合、リンクを再接続してもメッセージを解決できません。 短時間の一時的なネットワーク障害、ネットワークの停止、またはサービスによる 10 分間のアイドル タイムアウトの適用が原因で、リンクがデタッチされる可能性があります。 リンクの再接続は、リンクを必要とする操作 (つまり、メッセージの解決または受信) の一部として自動的に行われます。 この動作により、ロックの有効期限がまだ経過していない場合でも、
Reason
がMessageLockLost
またはSessionLockLost
であるServiceBusException
が発生する可能性があります。SessionLockLost
: セッションに対するロックの期限が切れたことを示します。 呼び出し元は、セッションの受け入れをもう一度試みる必要があります。 この例外は、セッションが有効なエンティティにのみ適用されます。 このエラーは、処理にロック期間より長い時間がかかり、セッション ロックが更新されない場合に発生します。 このエラーは、一時的なネットワークの問題が原因でリンクがデタッチされるときや、リンクが 10 分間アイドル状態になっているときにも、発生する可能性があります。 Service Bus サービスでは、ステートフルな AMQP プロトコルが使われます。 このプロトコルの性質上、メッセージが受信されてから解決されるまでの間に、クライアントとサービスを接続するリンクがデタッチされた場合、リンクを再接続してもメッセージを解決できません。 短時間の一時的なネットワーク障害、ネットワークの停止、またはサービスによる 10 分間のアイドル タイムアウトの適用が原因で、リンクがデタッチされる可能性があります。 リンクの再接続は、リンクを必要とする操作 (つまり、メッセージの解決または受信) の一部として自動的に行われます。 この動作により、ロックの有効期限がまだ経過していない場合でも、Reason
がMessageLockLost
またはSessionLockLost
であるServiceBusException
が発生する可能性があります。MessageNotFound
: このエラーは、エンティティに存在しないか、現在ロックされているメッセージのシーケンス番号で、遅延メッセージを受信しようとしたときに発生します。SessionCannotBeLocked
: ロックが既に他の場所で保持されているため、要求されたセッションをロックできないことを示します。 ロックの有効期限が切れたら、セッションを受け入れることができます。GeneralError
: 要求の処理中に Service Bus サービスでエラーが発生したことを示します。 このエラーは、多くの場合、サービスのアップグレードと再起動によって発生します。 これらのエラーは、自動的に再試行される一時的なエラーです。ServiceCommunicationProblem
: サービスとの通信中にエラーが発生したことを示します。 この問題は、一時的なネットワークの問題またはサービスの問題が原因である可能性があります。 これらのエラーは、自動的に再試行される一時的なエラーです。ServiceBusy
: 要求がサービスによって抑えられたことを示します。 要求が抑えられる可能性のある原因と、抑えられるのを回避する方法について詳しくは、こちらをご覧ください。 抑えられた要求は再試行されますが、クライアント ライブラリは、同じServiceBusClient
(またはそのクライアントから作成されたサブ型) を使ってさらに要求を試みる前に、自動的に 10 秒のバックオフを適用します。 エンティティのロック期間が 10 秒未満の場合、未解決のメッセージまたはロックされたセッションでメッセージまたはセッションのロックがで失われる可能性があるため、問題の原因になることがあります。 通常、抑えられた要求は正常に再試行されるため、生成された例外はエラーではなく警告としてログされます。特定の警告レベルのイベント ソース イベントは 43 です (RunOperation で例外が発生し、再試行が行われました)。MessagingEntityAlreadyExists
: 同じ名前のエンティティが同じ名前空間に存在することを示します。MessagingEntityDisabled
: メッセージング エンティティが無効になっています。 ポータルを使ってエンティティをもう一度有効にしてください。MessagingEntityNotFound
: Service Bus サービスで Service Bus リソースが見つかりません。
ServiceBusException の処理 - 例
ServiceBusException
を処理し、Reason
でフィルター処理する方法の例を次に示します。
try
{
// Receive messages using the receiver client
}
catch (ServiceBusException ex) when
(ex.Reason == ServiceBusFailureReason.ServiceTimeout)
{
// Take action based on a service timeout
}
その他の一般的な例外
ArgumentException
: クライアントとの対話時に指定されたパラメーターが無効な場合、クライアントはArgumentException
から派生するこの例外をスローします。 具体的なパラメーターと問題の性質については、Message
で確認できます。InvalidOperationException
: 現在の構成に対して無効な操作を実行しようとすると発生します。 通常、この例外は、その操作をサポートするようにクライアントが構成されていない場合に発生します。 多くの場合、クライアントに渡されるオプションを調整することで軽減できます。NotSupportedException
: 要求された操作がクライアントに対して有効であっても、現在の状態ではサポートされていない場合に発生します。 このシナリオに関する情報は、Message
で確認できます。AggregateException
: 操作で複数の例外が発生した可能性があり、それらが 1 つのエラーとして提示される場合に発生します。 この例外が最もよく発生するのは、Service Bus プロセッサまたは Service Bus セッション プロセッサの開始時または停止時です。
理由: QuotaExceeded
理由が QuotaExceeded
に設定された ServiceBusException は、特定のエンティティのクォータが超過したことを示します。
Note
Service Bus クォータについては、クォータに関する記事を参照してください。
キューとトピック
キューとトピックは、通常、キューのサイズに関連します。 エラー メッセージのプロパティには、次の例のようにさらに詳しい情報が含まれます。
Message: The maximum entity size has been reached or exceeded for Topic: 'xxx-xxx-xxx'.
Size of entity in bytes:1073742326, Max entity size in bytes:
1073741824..TrackingId:xxxxxxxxxxxxxxxxxxxxxxxxxx, TimeStamp:3/15/2013 7:50:18 AM
メッセージは、トピックがそのサイズの上限を超えたことを示します (この場合 1 GB (既定のサイズ上限))。
名前空間
名前空間の場合、QuotaExceeded 例外はアプリケーションが名前空間への最大接続数を超えたことを示す場合があります。 次に例を示します。
<tracking-id-guid>_G12 --->
System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]:
ConnectionsQuotaExceeded for namespace xxx.
一般的な原因
このエラーの 2 つの一般的な原因は、配信不能キューと機能していないメッセージ受信者です。
配信不能キュー リーダーがメッセージを完了できない状態でロックの有効期限が切れたときにメッセージがキュー/トピックに返されます。 これは、リーダーでメッセージの完了を妨げる例外が起きた場合に、発生する可能性があります。 メッセージは 10 回読み取られた後、既定で配信不能キューに移動します。 この動作は MaxDeliveryCount プロパティによって制御され、既定値は 10 です。 メッセージが配信不能キューに溜まるほど、領域が占有されます。
この問題を解決するには、他のキューの場合と同様に、配信不能キューからメッセージを読み取り、完了します。
受信者が停止しました。 受信者によるキューまたはサブスクリプションからのメッセージの受信が停止されています。 問題を特定するには、アクティブなメッセージの数を調べます。 アクティブなメッセージの数が大きいか増えている場合は、メッセージが読み取りより速く書き込まれています。
理由: MessageLockLost
原因
理由が MessageLockLost
に設定された ServiceBusException は、メッセージが PeekLock 受信モードを使って受信されていて、クライアントによって保持されているロックがサービス側で期限切れになったことを示します。
メッセージのロックは、さまざまな理由により期限切れになる場合があります。
- ロック タイマーが、クライアント アプリケーションによって更新される前に期限切れになっている。
- クライアント アプリケーションがロックを取得し、永続ストアにそれを保存してから再起動した。 再起動された後、クライアント アプリケーションは処理中のメッセージを調べて、メッセージを完了しようとしました。
この例外は、次のシナリオで発生する可能性もあります。
- サービスの更新
- OS の更新
- ロックを保持したままエンティティ (キュー、トピック、サブスクリプション) のプロパティを変更。
解決方法
クライアント アプリケーションは、MessageLockLostException を受信すると、それ以上メッセージを処理できません。 クライアント アプリケーションは必要に応じて分析のために例外のログ記録を検討できますが、クライアントはメッセージを破棄する "必要があります"。
メッセージに対するロックは有効期限が切れたため、キュー (またはサブスクリプション) に戻され、受信を呼び出す次のクライアント アプリケーションで処理できるようになります。
MaxDeliveryCount を超えた場合、メッセージは DeadLetterQueue に移動される可能性があります。
理由: SessionLockLost
原因
理由が MessageLockLost
に設定された ServiceBusException は、セッションが受け入れられ、クライアントによって保持されているロックがサービス側で期限切れになったときにスローされます。
セッションのロックは、さまざまな理由により期限切れになる場合があります。
- ロック タイマーが、クライアント アプリケーションによって更新される前に期限切れになっている。
- クライアント アプリケーションがロックを取得し、永続ストアにそれを保存してから再起動した。 再起動後、クライアント アプリケーションが、転送中のセッションを調べて、これらのセッション内のメッセージを処理しようとした。
この例外は、次のシナリオで発生する可能性もあります。
- サービスの更新
- OS の更新
- ロックを保持したままエンティティ (キュー、トピック、サブスクリプション) のプロパティを変更。
解決方法
クライアント アプリケーションは、SessionLockLostException を受け取ると、セッションでそれ以上メッセージを処理できません。 クライアント アプリケーションでは分析のために例外をログに記録することもできますが、クライアントはメッセージを破棄する "必要があります"。
セッションに対するロックは有効期限が切れたため、キュー (またはサブスクリプション) に戻され、セッションを受け入れる次のクライアント アプリケーションによってロックできます。 セッション ロックは、特定の時点で 1 つのクライアント アプリケーションによって保持されるため、順番どおりの処理が保証されます。
TimeoutException
TimeoutException は、ユーザーが開始した操作が操作タイムアウトより時間がかかっていることを示します。
ServicePointManager.DefaultConnectionLimit プロパティの値を確認する必要があります。この制限に達した場合も、TimeoutException が発生する可能性があります。
タイムアウトは、サービスを実行するリソースに対する Service Bus サービスの更新、(または) OS の更新など、メンテナンス操作中またはその間に発生することが予想されます。 OS の更新中は、エンティティが移動され、ノードが更新または再起動されるため、タイムアウトが発生する可能性があります。 Azure Service Bus サービスのサービス レベル アグリーメント (SLA) の詳細については、「Service Bus の SLA」を参照してください。
SocketException
原因
次の場合には、SocketException がスローされます。
- 指定された時間が経過してもホストが適切に応答しなかったため、接続試行が失敗した場合 (TCP エラー コード 10060)。
- 接続されたホストが応答できなかったため、確立された接続が失敗した場合。
- メッセージの処理中にエラーが発生したか、リモート ホストがタイムアウトを超えた場合。
- 基になるネットワーク リソースの問題。
解決方法
SocketException エラーは、アプリケーションをホストしている VM が名前 <mynamespace>.servicebus.windows.net
を対応する IP アドレスに変換できないことを示します。
IP アドレスへのマッピングで、次のコマンドが成功するかどうかを調べます。
PS C:\> nslookup <mynamespace>.servicebus.windows.net
次のような出力が提供される必要があります。
Name: <cloudappinstance>.cloudapp.net
Address: XX.XX.XXX.240
Aliases: <mynamespace>.servicebus.windows.net
上記の名前が、IP と名前空間のエイリアスに解決されない場合は、ネットワーク管理者と共にさらに調査します。 名前解決は、通常、顧客ネットワークのリソースである DNS サーバーを介して行われます。 DNS の解決が Azure DNS によって行われる場合は、Azure サポートにお問い合わせください。
名前解決が想定したとおりに機能している場合は、Azure Service Bus への接続が許可されているかどうかをこちらで確認してください。
UnauthorizedAccessException
UnauthorizedAccessException は、指定された資格情報では、要求されたアクションの実行が許可されないことを示します。 Message
プロパティには、エラーに関する詳細が含まれています。
ServiceBusClient
を構築するときに提供される承認の種類に応じて、これらの検証手順に従うことをお勧めします。
geo レプリケーションの例外
ServerBusyException
原因
- 非同期レプリケーション中 (レプリケーションのラグが 0 より大きい場合)、クライアントはサービス バスのエンティティ (キュー、トピック) に対して操作を試行するか、もしくは管理操作を実行しますが、プライマリとセカンダリのリージョン間のレプリケーションのラグが最大限許容されるレプリケーションのラグを秒単位で超えたため、操作を完了できません。
- 例: 新しいレプリケーションのラグが 38323 秒に達し、設定されたレプリケーションのラグの最大 (300 秒) を超えているため、操作が調整されています。 レプリケートされている最新の操作の、現在のレプリケーションのラグは 0 秒です。
- エンティティのレプリケーション キューが最大サイズ (バイト単位) を超えています。 レプリケーション キューの最大サイズ (バイト単位) は、Service Bus によって設定される内部制限です。
- 例: レプリケーション キューのサイズ 73128000 はしきい値 67108864 を超えています。
- 同期レプリケーションでは、別の要求のレプリケートを待機している間に要求がタイムアウトします。
- 例: skarri-stroage-exp1(westus3)/q1:MessagingJournal のクライアント アプリケーションからの大量の要求。 他のリージョンへのレプリケーションが進行中です。
解決方法
- 特定のワークロードを処理する時間をサービスに与えるために、クライアントをバックオフする必要があります。その後、クライアントは再試行するはずです。
タイムアウト
原因
- Geo DR でのタイムアウト例外は、クライアントが指定したタイムアウト内で操作が完了しなかったことを意味します。
- 同期レプリケーションでは、操作のプライマリ リージョンの書き込みとセカンダリ リージョンへのレプリケーションが、操作のタイムアウトのスコープ内にあります。
- 非同期レプリケーションでは、操作のプライマリ リージョンの書き込みが、操作のタイムアウトのスコープ内にありますが、操作のセカンダリ リージョンへのレプリケーションは、操作のタイムアウトのスコープ内にありません。
- 例: オブジェクト メッセージに割り当てられた時間 00:01:00 内に操作が完了しませんでした。 (ServiceTimeout)。
解決方法
- クライアントは操作を再試行する必要があります。
- タイムアウトした操作の一部のステップは完了している場合があります。 タイムアウトした操作がプライマリ リージョンと一部のセカンダリ リージョンに書き込まれている可能性があります。 操作がプライマリ リージョンに書き込まれている場合、クライアントのタイムアウトに関係なく、最終的にはすべてのセカンダリ リージョンにレプリケートされます。
BadRequest
原因
- 計画フェールオーバー中は、セカンダリ リージョンが追いつけるように、プライマリ リージョンが一時的に読み取り専用に設定されます。 クライアントがこの一時的な読み取り専用状態にあるときにプライマリ リージョンへの書き込み操作を試みると、クライアントは BadRequest 例外を受け取ります。
- 例: レプリケーション ロール スイッチが進行中、プライマリ レプリカ: <entity-name> は読み取り専用です。
解決方法
- 書き込み操作が成功するには、クライアントが計画フェールオーバーの完了を待つ必要があります。
- 計画フェールオーバーに時間がかかりすぎる場合は、代わりに強制フェールオーバーをトリガーできます。
次のステップ
Service Bus の詳細な .NET API リファレンスについては、「Azure .NET API reference」(Azure .NET API リファレンス) を参照してください。 トラブルシューティングのヒントについては、トラブルシューティング ガイドに関する記事をご覧ください。