Azure:具有唯一键的循环(环)队列

时间:2015-08-12 22:31:09

标签: azure azureservicebus

对于我的应用程序,我需要组织一个循环(环)队列。这意味着任何已处理的消息都会立即进入队列末尾以进行连续处理。

例如:

  1. 队列:ABC
  2. 接收方进程A
  3. 队列:BCA
  4. 2和3应该原子地进行。所以我们永远不会丢失A或任何其他消息。

    另一个要求是忽略重复。所以队列中应该总是有一个A。即使发件人推送另一个A项。 A指的是此处消息的一些唯一(主要)密钥。

    我寻找使用Azure Service Bus,但我找不到如何满足这两个要求。是否可以使用Service Bus实现方案?如果没有,最好的选择是什么?

2 个答案:

答案 0 :(得分:2)

这种队列可以通过Service Bus 会话实现。会话提供“分组依据”机制,因此我们可以将唯一密钥分配给消息的SessionId,然后在组中接收消息,忽略除第一个消息之外的组中的所有消息。

<强>实施

1)创建一个RequiresSession设置为true的队列:

var queueDescription = new QueueDescription("CircularQueue")
{
    RequiresSession = true,
};
await namespaceManager.CreateQueueAsync(queueDescription);

2)将消息发送到队列时,将SessionId设置为您的唯一键值:

var message = new BrokeredMessage($"Message body")
{
    MessageId = "MESSAGE_UNIQUE_KEY",
    SessionId = "MESSAGE_UNIQUE_KEY"
};
await queueClient.SendAsync(message);

3)使用会话接收消息:

while (true)
{
    var session = await queueClient.AcceptMessageSessionAsync(TimeSpan.FromSeconds(10));
    if (session == null)
        continue;

    try
    {
        var messages = (await session.ReceiveBatchAsync(100)).ToList();

        if (messages.Count == 0)
            continue;

        var message = messages[0];

        ProcessMessage(message);

        await queueClient.SendAsync(message.Clone());
        await session.CompleteBatchAsync(messages.Select(msg => msg.LockToken));
    }
    finally
    {
        await session.CloseAsync();
    }
}

答案 1 :(得分:0)

基于我对Azure Service Bus的了解,我相信这两个要求都可以单独实现,但我不确定它们是如何一起完成的。

  

消息循环

据我了解,Azure Service Bus支持First-In-First-Out (FIFO)行为。您可以做的是以Receive and Delete模式从队列顶部获取消息(例如A),然后将消息重新插入队列中。由于您正在创建新消息,因此它将发布到队列的末尾。

  

避免重复消息

Service Bus Queues有一个名为RequiresDuplicateDetection的布尔属性,相应地设置此值将防止插入重复的消息。只需简单搜索Azure Service Bus Duplicate Detection即可获得许多示例。