11

ワーカー ロール内で使用する Azure Service Bus コードの基本的なラッパーを以下に示します。これServiceBusClientは、worker ロールが実行されるたびにインスタンス化されます。その後、列挙するアイテムがなくなるまで、キューにアクセスするために使用されます。

public class ServiceBusClient : IDisposable, IServiceBusClient
{
    private const int DEFAULT_WAIT_TIME_IN_SECONDS = 120;

    private const string SERVICE_BUS_CONNECTION_STRING_KEY = "service.bus.connection.string";

    private readonly MessagingFactory _messagingFactory;

    private readonly NamespaceManager _namespaceManager;

    private readonly QueueClient _queueClient;

    private readonly ISettingsManager _settingsManager;

    public ServiceBusClient(ISettingsManager settingsManager, string queueName)
    {
        _settingsManager = settingsManager;

        var connectionString = _settingsManager.GetSetting<string>(SERVICE_BUS_CONNECTION_STRING_KEY);

        _namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString);
        _messagingFactory = MessagingFactory.CreateFromConnectionString(connectionString);

        _queueClient = GetOrCreateQueue(queueName);
    }

    public void Dispose()
    {
        _messagingFactory.Close();
    }

    public BrokeredMessage ReceiveTopMessage()
    {
        return _queueClient.Receive(TimeSpan.FromSeconds(DEFAULT_WAIT_TIME_IN_SECONDS));
    }

    public void SendMessage(object bodyObject)
    {
        var message = new BrokeredMessage(bodyObject);

        _queueClient.Send(message);
    }

    private QueueClient GetOrCreateQueue(string queueName)
    {
        var queue = !_namespaceManager.QueueExists(queueName)
                        ? _namespaceManager.CreateQueue(queueName)
                        : _namespaceManager.GetQueue(queueName);

        return _messagingFactory.CreateQueueClient(queue.Path, ReceiveMode.PeekLock);
    }

}

ご覧のとおり、コンストラクター内NamespaceManagerで ,MessagingFactoryを初期化します。これらは、呼び出し時にQueueClient再利用され、メソッドを使用して接続が閉じられます。SendMessage()ReceiveTopMessage()Dispose()

私の質問は、私が使用しているアプローチが安全かどうかです。worker ロールがキュー上のすべてのメッセージを列挙している間、の 1 つのインスタンスをQueueClient開いたままにします ( への呼び出し間の長い待機でかなり長い間接続を開いたままにしておくことができるプロセスReceiveTopMessage()) は、一時的な問題なしで一貫して動作しますか?毎回接続を開いたり閉じたりするのは賢明ですか?

余談として; Microsoft Service Bus コードで行われる一時的な障害処理はどのように行われますか? デフォルトで実施されますか、それとも一時的な障害処理フレームワークを実装する必要がありますか?

4

1 に答える 1

11

このQueueClientクラスは、作成に使用された MessagingFactory オブジェクトによって管理される接続を使用します。複数のリクエストに対して同じクライアント オブジェクトを再利用することをお勧めします。Service Bus Brokered Messaging を使用したパフォーマンス向上のためのベスト プラクティスに記載されているとおり:

Service Bus を使用すると、クライアントは Service Bus クライアント プロトコルと HTTP の 2 つのプロトコルを介してメッセージを送受信できます。Service Bus クライアント プロトコルは、メッセージ ファクトリが存在する限り Service Bus サービスへの接続を維持するため、より効率的です。また、バッチ処理とプリフェッチも実装しています。Service Bus クライアント プロトコルは、.NET マネージ API を使用する .NET アプリケーションで使用できます。(...) QueueClient や MessageSender などの Service Bus クライアント オブジェクトは、接続の内部管理も提供する MessagingFactory オブジェクトを介して作成されます。メッセージを送信した後、メッセージング ファクトリまたはキュー、トピック、およびサブスクリプション クライアントを閉じて、次のメッセージを送信するときにそれらを再作成しないでください。メッセージング ファクトリを閉じると Service Bus サービスへの接続が削除され、ファクトリの再作成時に新しい接続が確立されます。接続の確立はコストのかかる操作ですが、同じファクトリ オブジェクトとクライアント オブジェクトを複数の操作に再利用することで回避できます。(...) 同じファクトリによって作成されたすべてのクライアント (受信者に加えて送信者) は、1 つの TCP 接続を共有します。

一時的な障害処理に関して、リクエストを再試行する必要があるかどうかを決定するQueueClientRetryPolicyプロパティがあります。また、Transient Fault Handling Framework に取って代わるTransient Fault Handling Application Blockもあります。

メッセージ受信ループに関しては、Implementing Reliable Message Receive Loopsにガイダンスがあります。Microsoft は、適切に作成された回復力のあるメッセージ受信ループを実装するのが難しいことを認識しているため、代わりにイベント ドリブン メッセージ プログラミング モデルを導入しました。

于 2013-07-11T19:51:27.653 に答える