1

キューからアイテムを処理するワーカー ロールがあります。これは基本的に、アイテムをキューから取り出して非同期的に処理する無限ループです。

2 つの構成設定 (PollingIntervalおよびMessageGetLimit) があり、変更されたときに worker ロールが取得するようにします (したがって、再起動は必要ありません)。

private TimeSpan PollingInterval 
{
    get
    {
        return TimeSpan.FromSeconds(Convert.ToInt32(RoleEnvironment.GetConfigurationSettingValue("PollingIntervalSeconds")));
    }
}

private int MessageGetLimit 
{ 
    get 
    {
        return Convert.ToInt32(RoleEnvironment.GetConfigurationSettingValue("MessageGetLimit"));
    } 
}

public override void Run()
{
    while (true)
    {
        var messages = queue.GetMessages(MessageGetLimit);

        if (messages.Count() > 0)
        {
            ProcessQueueMessages(messages);
        }
        else
        {
            Task.Delay(PollingInterval);
        }
    }
}

問題:

ピーク時には、while ループが 1 秒あたり数回実行される可能性があります。これは、構成アイテムを 1 日あたり最大 100,000 回クエリすることを意味します。

これは有害または非効率的ですか?

4

2 に答える 2

3

ジョンの答えは、環境変更/変更イベントを使用して再起動せずに設定を変更するのに適していますが、おそらくより良い方法は、指数バックオフ ポリシーを使用してポーリングをより効率的にすることだと思います。コードの動作をそれ自体でよりスマートにすることで、コードを微調整する頻度を減らすことができます。これらの環境設定を更新するたびに、すべてのインスタンスにロールアウトする必要があることに注意してください。実行しているインスタンスの数によっては、少し時間がかかる場合があります。また、人間が関与しなければならないステップをここに入れています。

Windows Azure ストレージ キューを使用しています。つまり、GetMessages が実行されるたびに、サービスが呼び出され、0 個以上のメッセージが取得されます (MessageGetLimit まで)。それを要求するたびに、トランザクションが請求されます。さて、取引は本当に安いことを理解してください。1 日 100,000 トランザクションでも 1 日あたり 0.01 ドルです。ただし、ループの速度を過小評価しないでください。:) それよりも多くのスループットが得られる可能性があり、複数のワーカー ロール インスタンスがある場合は、これが加算されます (ただし、実際にインスタンス自体を実行する場合と比較すると、まだ非常に少額です)。

より効率的なパスは、キューからメッセージを読み取るための指数バックオフ アプローチを導入することです。簡単な例については、Maarten による次の投稿をご覧ください: http://www.developerfusion.com/article/120619/advanced-scenarios-with-windows-azure-queues/。バックオフ アプローチと、キューの深さに基づくワーカー ロールの自動スケーリングを組み合わせると、人による設定の調整にあまり依存しないソリューションが得られます。インスタンス数の最小値と最大値を入力し、次にメッセージを要求したときにメッセージが表示された回数に基づいてプルするメッセージの数を調整します。ここには、関与を減らすための多くのオプションがあります。そして効率的なシステムを持っています。

また、Windows Azure サービス バス キューはロング ポーリングを実装しているため、作業がキューにヒットするのを待っている間のトランザクションがはるかに少なくなります。

于 2013-10-28T12:15:43.067 に答える