mcpField
A
azure-servicebus-dotnet

azure-servicebus-dotnet

github.com/sickn33クラウド・DevOps48.7k52 回インストール今日更新
リポジトリ

azure-servicebus-dotnet について

azure-servicebus-dotnetは、Azure.Messaging.ServiceBusを扱う.NET開発者向けのスキルです。キューやトピックのメッセージング、処理、セッション、管理、トランザクションの実装方法を示します。

主な機能

  1. 01メッセージの送受信
  2. 02バックグラウンドでのメッセージ処理
  3. 03セッションによる順序処理
  4. 04デッドレターメッセージの処理
  5. 05キュー、トピック、サブスクリプションの管理
  6. 06エンティティ間トランザクションの設定

活用シーン

  1. 01.NETのキューコンシューマー構築
  2. 02トピックやサブスクリプションへのメッセージ発行
  3. 03順序付きセッションメッセージの処理

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/sickn33/agentic-awesome-skills --skill azure-servicebus-dotnet

インストール後、Claude Code で/azure-servicebus-dotnetを入力して読み込まれたか確認します。

詳細

Azure.Messaging.ServiceBus (.NET)

キュー、トピック、サブスクリプション、セッションを利用してメッセージを確実に配信するためのエンタープライズ向けメッセージング SDK です。

インストール

dotnet add package Azure.Messaging.ServiceBus
dotnet add package Azure.Identity

SDK のバージョン基準例:v7.20.1。スニペットを調整する前に、インストール済みのパッケージと互換性のある API を確認してください。

環境変数

AZURE_SERVICEBUS_FULLY_QUALIFIED_NAMESPACE=<namespace>.servicebus.windows.net
# Or connection string (less secure)
AZURE_SERVICEBUS_CONNECTION_STRING=Endpoint=sb://...

認証

Microsoft Entra ID(推奨)
using Azure.Identity;
using Azure.Messaging.ServiceBus;

string fullyQualifiedNamespace = "<namespace>.servicebus.windows.net";
await using ServiceBusClient client = new(fullyQualifiedNamespace, new DefaultAzureCredential());
接続文字列
string connectionString = "<connection_string>";
await using ServiceBusClient client = new(connectionString);
ASP.NET Core の依存関係の挿入
services.AddAzureClients(builder =>
{
    builder.AddServiceBusClientWithNamespace("<namespace>.servicebus.windows.net");
    builder.UseCredential(new DefaultAzureCredential());
});

クライアントの階層

ServiceBusClient
├── CreateSender(queueOrTopicName)      → ServiceBusSender
├── CreateReceiver(queueName)           → ServiceBusReceiver
├── CreateReceiver(topicName, subName)  → ServiceBusReceiver
├── AcceptNextSessionAsync(queueName)   → ServiceBusSessionReceiver
├── CreateProcessor(queueName)          → ServiceBusProcessor
└── CreateSessionProcessor(queueName)   → ServiceBusSessionProcessor

ServiceBusAdministrationClient (separate client for CRUD)

スニペットはそれぞれ独立して使用し、CRUD には Azure.Messaging.ServiceBus.Administration を、TransactionScope には System.Transactions をインポートしてください。名前空間とエンティティを確認し、最小権限の送信者/受信者/管理者ロールを使用してください。受信結果が null の場合があります。DLQ とトランザクションの例でも同様に null を確認してください。完了するとメッセージは削除されます。まず永続的なビジネス処理を実行し、再配信に備えて冪等にし、結果が不確かな送信や決済を照合してください。すべての例外で放棄すると、有害メッセージのループが発生するおそれがあります。メッセージ本文や、機密性の高いペイロードを含む未加工の例外をログに記録しないでください。セッション対応キューにはセッションレシーバーが必要です。基本的な受信例では、異なるセッション非対応キューを使用しています。プロセッサーは非同期で破棄し、ロックの更新とシャットダウンのポリシーに上限を設けてください。

主なワークフロー

1. メッセージの送信
await using ServiceBusClient client = new(fullyQualifiedNamespace, new DefaultAzureCredential());
ServiceBusSender sender = client.CreateSender("my-queue");

// Single message
ServiceBusMessage message = new("Hello world!");
await sender.SendMessageAsync(message);

// Safe batching (recommended)
using ServiceBusMessageBatch batch = await sender.CreateMessageBatchAsync();
if (!batch.TryAddMessage(new ServiceBusMessage("Message 1")))
    throw new InvalidOperationException("Message 1 exceeds the batch capacity");
if (!batch.TryAddMessage(new ServiceBusMessage("Message 2")))
    throw new InvalidOperationException("Message 2 exceeds remaining batch capacity; flush and retry in a new batch");
await sender.SendMessagesAsync(batch);
2. メッセージの受信
ServiceBusReceiver receiver = client.CreateReceiver("my-queue");

// Single message
ServiceBusReceivedMessage message = await receiver.ReceiveMessageAsync();
if (message is null) return; // A timed receive can return no message
string body = message.Body.ToString();
Console.WriteLine(body);

// Complete the message (removes from queue)
await receiver.CompleteMessageAsync(message);

// Batch receive
IReadOnlyList<ServiceBusReceivedMessage> messages = await receiver.ReceiveMessagesAsync(maxMessages: 10);
foreach (var msg in messages)
{
    Console.WriteLine(msg.Body.ToString());
    await receiver.CompleteMessageAsync(msg);
}
3. メッセージの決済
// Complete - removes message from queue
await receiver.CompleteMessageAsync(message);

// Abandon - releases lock, message can be received again
await receiver.AbandonMessageAsync(message);

// Defer - prevents normal receive, use ReceiveDeferredMessageAsync
await receiver.DeferMessageAsync(message);

// Dead Letter - moves to dead letter subqueue
await receiver.DeadLetterMessageAsync(message, "InvalidFormat", "Message body was not valid JSON");
4. プロセッサーを使用したバックグラウンド処理
ServiceBusProcessor processor = client.CreateProcessor("my-queue", new ServiceBusProcessorOptions
{
    AutoCompleteMessages = false,
    MaxConcurrentCalls = 2
});

processor.ProcessMessageAsync += async (args) =>
{
    try
    {
        string body = args.Message.Body.ToString();
        Console.WriteLine($"Received: {body}");
        await args.CompleteMessageAsync(args.Message);
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Error processing: {ex.Message}");
        await args.AbandonMessageAsync(args.Message);
    }
};

processor.ProcessErrorAsync += (args) =>
{
    Console.WriteLine($"Error source: {args.ErrorSource}");
    Console.WriteLine($"Entity: {args.EntityPath}");
    Console.WriteLine($"Exception: {args.Exception}");
    return Task.CompletedTask;
};

await processor.StartProcessingAsync();
// ... application runs
await processor.StopProcessingAsync();
5. セッション(順序どおりの処理)
// Send session message
ServiceBusMessage message = new("Hello")
{
    SessionId = "order-123"
};
await sender.SendMessageAsync(message);

// Receive from next available session
ServiceBusSessionReceiver receiver = await client.AcceptNextSessionAsync("my-queue");

// Or receive from specific session
ServiceBusSessionReceiver receiver = await client.AcceptSessionAsync("my-queue", "order-123");

// Session state management
await receiver.SetSessionStateAsync(new BinaryData("processing"));
BinaryData state = await receiver.GetSessionStateAsync();

// Renew session lock
await receiver.RenewSessionLockAsync();
6. 配信不能キュー
// Receive from dead letter queue
ServiceBusReceiver dlqReceiver = client.CreateReceiver("my-queue", new ServiceBusReceiverOptions
{
    SubQueue = SubQueue.DeadLetter
});

ServiceBusReceivedMessage dlqMessage = await dlqReceiver.ReceiveMessageAsync();

// Access dead letter metadata
string reason = dlqMessage.DeadLetterReason;
string description = dlqMessage.DeadLetterErrorDescription;
Console.WriteLine($"Dead letter reason: {reason} - {description}");
7. トピックとサブスクリプション
// Send to topic
ServiceBusSender topicSender = client.CreateSender("my-topic");
await topicSender.SendMessageAsync(new ServiceBusMessage("Broadcast message"));

// Receive from subscription
ServiceBusReceiver subReceiver = client.CreateReceiver("my-topic", "my-subscription");
var message = await subReceiver.ReceiveMessageAsync();
8. 管理(CRUD)
var adminClient = new ServiceBusAdministrationClient(
    fullyQualifiedNamespace, 
    new DefaultAzureCredential());

// Create queue
var options = new CreateQueueOptions("my-queue")
{
    MaxDeliveryCount = 10,
    LockDuration = TimeSpan.FromSeconds(30),
    RequiresSession = true,
    DeadLetteringOnMessageExpiration = true
};
QueueProperties queue = await adminClient.CreateQueueAsync(options);

// Update queue
queue.LockDuration = TimeSpan.FromSeconds(60);
await adminClient.UpdateQueueAsync(queue);

// Create topic and subscription
await adminClient.CreateTopicAsync(new CreateTopicOptions("my-topic"));
await adminClient.CreateSubscriptionAsync(new CreateSubscriptionOptions("my-topic", "my-subscription"));

// Delete
await adminClient.DeleteQueueAsync("my-queue");
9. エンティティ間のトランザクション
var options = new ServiceBusClientOptions { EnableCrossEntityTransactions = true };
await using var client = new ServiceBusClient(connectionString, options);

ServiceBusReceiver receiverA = client.CreateReceiver("queueA");
ServiceBusSender senderB = client.CreateSender("queueB");

ServiceBusReceivedMessage receivedMessage = await receiverA.ReceiveMessageAsync();

using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
    await receiverA.CompleteMessageAsync(receivedMessage);
    await senderB.SendMessageAsync(new ServiceBusMessage("Forwarded"));
    ts.Complete();
}

主な型のリファレンス

型用途
ServiceBusClientメインのエントリーポイント。接続を管理します
ServiceBusSenderキュー/トピックにメッセージを送信します
ServiceBusReceiverキュー/サブスクリプションからメッセージを受信します
ServiceBusSessionReceiverセッションメッセージを受信します
ServiceBusProcessorバックグラウンドでメッセージを処理します
ServiceBusSessionProcessorバックグラウンドでセッションメッセージを処理します
ServiceBusAdministrationClientキュー/トピック/サブスクリプションの CRUD を行います
ServiceBusMessage送信するメッセージ
ServiceBusReceivedMessageメタデータを含む受信済みメッセージ
ServiceBusMessageBatchメッセージのバッチ

ベストプラクティス

  1. シングルトンを使用する — クライアント、送信者、受信者、プロセッサーはスレッドセーフです
  2. 必ず破棄する — await using を使用するか、DisposeAsync() を呼び出してください
  3. 破棄の順序 — まず送信者/受信者/プロセッサーを閉じ、その後にクライアントを閉じてください
  4. DefaultAzureCredential を使用する — 本番環境では接続文字列よりも優先してください
  5. バックグラウンド処理にはプロセッサーを使用する — ロックの更新を自動的に処理します
  6. 安全にバッチ処理する — CreateMessageBatchAsync() と TryAddMessage() を使用してください
  7. 一時的なエラーに対処する — ServiceBusException.Reason を使用してください
  8. トランスポートを設定する — ポート 5671/5672 がブロックされている場合は AmqpWebSockets を使用してください
  9. 適切なロック期間を設定する — 既定値は 30 秒です
  10. 順序制御にはセッションを使用する — セッション内では FIFO になります

エラー処理

try
{
    await sender.SendMessageAsync(message);
}
catch (ServiceBusException ex) when (ex.Reason == ServiceBusFailureReason.ServiceBusy)
{
    // Retry with backoff
}
catch (ServiceBusException ex)
{
    Console.WriteLine($"Service Bus Error: {ex.Reason} - {ex.Message}");
}

関連 SDK

SDK用途インストール
Azure.Messaging.ServiceBusService Bus(この SDK)dotnet add package Azure.Messaging.ServiceBus
Azure.Messaging.EventHubsイベントストリーミングdotnet add package Azure.Messaging.EventHubs
Azure.Messaging.EventGridイベントルーティングdotnet add package Azure.Messaging.EventGrid

参考リンク

リソースURL
NuGet パッケージhttps://www.nuget.org/packages/Azure.Messaging.ServiceBus
API リファレンスhttps://learn.microsoft.com/dotnet/api/azure.messaging.servicebus
GitHub ソースhttps://github.com/Azure/azure-sdk-for-net/tree/main/sdk/servicebus/Azure.Messaging.ServiceBus
トラブルシューティングhttps://github.com/Azure/azure-sdk-for-net/blob/main/sdk/servicebus/Azure.Messaging.ServiceBus/TROUBLESHOOTING.md

使用するタイミング

このスキルは、概要で説明されているワークフローまたはアクションを実行する場合に適用できます。

制限事項

  • このスキルは、タスクが上記のスコープに明確に一致する場合にのみ使用してください。
  • 出力を、環境固有の検証、テスト、または専門家によるレビューの代替として扱わないでください。
  • 必要な入力、権限、安全境界、または成功基準が欠けている場合は、停止して明確化を求めてください。

コメント