3

我正在尝试在 Azure 中构建一个简单的 Web API REST 服务,并在后端使用服务总线队列工作程序。我可以很好地从 Web API 向工作人员发送一条消息。但是,我试图发送更多消息只是为了看看一切如何运作。所以,我创建了一个简单的控制器,如下所示:

for (int i = 0; i < 100; i++)
{
    var msg = new BrokeredMessage("Ping");
    BioConnector.QueueConnector.OrdersQueueClient.Send(msg);
}

当我调用控制器时,我只收到大约 1/2 左右的工人收到的消息。其余的似乎被丢弃了。

4

4 回答 4

3

使用此处发布的示例代码,我无法获得大约一半的消息,因此我编写了自己的测试代码。我已经尝试过超过 100 条队列消息,并且始终有 100% 的发送/接收奇偶校验。也许您对代码有类似的问题。

  1. 创建一个新的 C# 控制台项目。
  2. 添加对位于C:\Program Files\Microsoft SDKs\Windows Azure.NET SDK\2012-06\ref\Microsoft.ServiceBus.dll中的 Microsoft.ServiceBus 程序集的引用。
  3. 在 app.config 中,使用您自己提供的值将其更改为:

    <appSettings>
        <add key="Microsoft.ServiceBus.ConnectionString" value="Endpoint=sb://blahblah.servicebus.windows.net/;SharedSecretIssuer=owner;SharedSecretValue=pDk0b....=" />
    </appSettings>
    
  4. 添加这些 using 指令:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Xml;
    using System.Xml.Linq;
    using Microsoft.ServiceBus;
    using Microsoft.ServiceBus.Messaging;
    using System.Configuration;
    using System.Threading;
    
  5. 将代码方法更改为以下内容:

    class Program
    {
        static void Main(string[] args)
        {
            string connectionString = ConfigurationSettings.AppSettings["Microsoft.ServiceBus.ConnectionString"];
            var namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString);
            QueueDescription queueDesc = new QueueDescription("TestQueue");
            if (!namespaceManager.QueueExists(queueDesc.Path))
            {
                namespaceManager.CreateQueue(queueDesc);
            }
            QueueClient topicClient = QueueClient.CreateFromConnectionString(connectionString, queueDesc.Path);
            int sentMsgCount = 0;
            int recdMsgCount = 0;
    
            for (int i = 0; i < 100; i++)
            {
                BrokeredMessage msg = new BrokeredMessage("Test message " + i);
                topicClient.Send(msg);
                sentMsgCount++;
                Console.WriteLine("Sent Message: " + msg);
            }
    
            QueueClient subClient = QueueClient.CreateFromConnectionString(connectionString, queueDesc.Path);
    
            bool moreMessages = true;
            while (moreMessages)
            {
                BrokeredMessage recdMsg = subClient.Receive(TimeSpan.FromSeconds(3));
                if (recdMsg != null)
                {
                    Console.WriteLine("Received Message: " + recdMsg);
                    recdMsgCount++;
                    recdMsg.Complete();
                }
                else
                {
                    moreMessages = false;
                }
            }
            Console.WriteLine("# of sent msgs: " + sentMsgCount + ", # of rec'd msgs: " + recdMsgCount);
            Console.Read();
        }
    }
    
于 2013-03-10T10:34:59.980 回答
2

Azure 服务总线提供持久消息传递,因此您不会丢失任何消息。需要进一步调查的一些项目:1)是否有另一个工作角色实例正在从该队列中提取消息 2)您是否使用 peek-lock 作为接收模式,因为这将是保证至少一次交付的唯一方法。接收和删除模式没有保证 3) 消息是否由于消息过期或超过最大传递计数而进入死信队列,即它们被接收但未完成多次 4) 如果上述均不适用,则引发支持票证和 Azure 产品团队可以调查这些症状,因为正如我所提到的,这是一个持久的消息传递系统,因此不会“丢失”任何消息。

于 2013-03-10T18:11:41.393 回答
2

这是一个奇怪的问题。通过随机浏览“尝试的东西”,我最终更改了队列的字符串名称,然后一切都重新开始工作。除了队列的名称之外,我没有更改任何内容 - 根本没有更改任何配置参数。

Azure 上的特定队列似乎有问题。

于 2013-03-10T17:11:27.833 回答
0

我的项目中有WindowsAzure.ServiceBus NuGet 包,用于QueueClient.Send()发送消息并面临相同的消息丢失问题。

我完全解决问题的解决方案:

在发送端,我不得不使用 REST API 来发送消息

在接收端,这就是我提取消息正文的方式:

using (var stream = brokeredMessage.GetBody<Stream>())
{
    using (var streamReader = new StreamReader(stream, Encoding.UTF8))
    {
        var msg = streamReader.ReadToEnd();
        // Convert the JSON message to an object
        // var obj = JsonConvert.DeserializeObject<ObjectType>(msg);
    }
}
于 2018-11-29T10:23:25.517 回答