2

遅延キューは、各メッセージに遅延時間が関連付けられているキューであり、メッセージはその遅延が期限切れになった場合にのみ取得できます。キューの先頭は、過去に遅延が期限切れになったメッセージです。遅延の期限が切れていない場合、ヘッドはなく、デキューは null を返します。

実際、私は Azure を使用してクラウド アプリケーションを作成していますが、Azure では FIFO キューのみが使用可能であり、優先/遅延キューは使用できません。だから私はここに来て、誰かが私が正しい方向に向かうことができる場所からいくつかの指針を与えることができるかどうかを調べました. 私はよくグーグルで検索しましたが、Java での遅延キューの実装についてしか知りませんでした。一般的な遅延キューについて説明している標準的なチュートリアル/研究論文はありません。

編集:

私はコードを持っていますか?
実際には、まずこれを設計してマネージャーに提示する必要があります。設計が完成したら、コーディングを開始できるのは私だけです。

シナリオの詳細
マスター/スレーブ モデルに基づく分散アプリケーションです。マスターはメッセージを生成し、それらを Azure Service Bus キューに入れます。複数のスレーブ (複数のマシンで実行されている) がキューから読み取ってそれらを処理します。マスターがダウンした場合、スレーブの 1 つがマスターとして機能し、メッセージの生成を開始します。マスターに状態情報を保存したくありません。マスターがダウンした場合、その状態情報もすべて一緒に保存されるからです。

4

3 に答える 3

11

Windows Azure キュー メッセージには、メッセージをキューに挿入するときに指定する秒単位の遅延があります。そのタイムアウト遅延が発生するまで、メッセージは表示されません。API の詳細については、この MSDN の記事を参照してください。

非表示タイムアウトは、さまざまな言語の SDK 実装にも実装されています。C# を使用しているため、AddMessage()呼び出しは次のようになります。の 3 番目のパラメータがAddMessage()非表示タイムアウトを指定していることに注意してください。

        var acct = CloudStorageAccount.DevelopmentStorageAccount;
        var queueClient = acct.CreateCloudQueueClient();
        var queue = queueClient.GetQueueReference("myqueue");
        queue.CreateIfNotExist();

        var msg = new CloudQueueMessage("test message");
        queue.AddMessage(msg, TimeSpan.FromHours(2), TimeSpan.FromMinutes(30));
于 2013-01-04T15:29:55.920 に答える
3

したがって、最初に、優先度付きキューの実装が必要になります。これは私が少し前に書いたものです。おそらく理想的ではありません。それは小さなAPIを持っており、おそらくより良いパフォーマンスを発揮する可能性がありますが、それは十分な出発点です:

public class PriorityQueue<TPriority, TElement>
{
    SortedDictionary<TPriority, Queue<TElement>> dictionary = new SortedDictionary<TPriority, Queue<TElement>>();
    public PriorityQueue()
    {
    }

    public Tuple<TPriority, TElement> Peek()
    {
        var firstPair = dictionary.First();
        return Tuple.Create(firstPair.Key, firstPair.Value.First());
    }

    public TElement Pop()
    {
        var firstPair = dictionary.First();
        TElement output = firstPair.Value.Dequeue();

        if (!firstPair.Value.Any())
            dictionary.Remove(firstPair.Key);

        return output;
    }

    public void Push(TPriority priority, TElement element)
    {
        Queue<TElement> queue;
        if (dictionary.TryGetValue(priority, out queue))
        {
            queue.Enqueue(element);
        }
        else
        {
            var newQueue = new Queue<TElement>();
            newQueue.Enqueue(element);
            dictionary.Add(priority, newQueue);
        }
    }
}

遅延キューは、それをラップするときに十分に単純です。

public class DelayQueue<T>
{
    private PriorityQueue<DateTime, T> queue = new PriorityQueue<DateTime, T>();
    public void Enqueue(T item, int delay)
    {
        queue.Push(DateTime.Now.AddMilliseconds(delay), item);
    }

    public T Dequeue()
    {
        if (queue.Peek().Item1 > DateTime.Now)
            return queue.Pop();
        else
            return default(T);
    }
}
于 2013-01-04T15:30:49.197 に答える
0

アイテムをデキューする2段階のプロセスでキューを作成するのはどうですか。高レベルのプロセスは次のとおりです。

  • FIFOキューの最初のアイテムをデキューします。不可視性をN分に設定します(不可視性を決定したものは何でも)-これにより、キューに存在しなかったかのように、アイテムを一定期間非表示にすることができます。これが私が参照しているNextVisibleTimeプロパティです

  • DequeueCountプロパティを確認します-デキューカウントが0の場合、このアイテムがデキューされたのはこれが初めてでした。アイテムを無視して次に進みます。不可視性が設定されているため、時間になるまで再度フェッチされることはありません。デキュー数が1以上の場合は、一度デキューされており、必要な時間非表示に設定されている必要があります。

これにより、遅延キューを実装できるようになります。他の方法も考えられます。たとえば、作成時間としてのキュー内の各アイテム。これを使用して、アイテムを非表示にしておく必要がある時間を動的に計算できます。プロパティの非表示を変更するには、次の方法を確認してください:http: //msdn.microsoft.com/en-us/library/microsoft.windowsazure.storageclient.cloudqueue.updatemessage.aspx

于 2013-01-04T15:30:23.923 に答える