Odd Behavior of Azure Service Bus ReceiveBatch()

十年热恋 提交于 2019-12-05 17:22:23

问题


Working with a Azure Service Bus Topic currently and running into an issue receiving my messages using ReceiveBatch method. The issue is that the expected results are not actually the results that I am getting. Here is the basic code setup, use cases are below:

    SubscriptionClient client = SubscriptionClient.CreateFromConnectionString(connectionString, convoTopic, subName);

    IEnumerable<BrokeredMessage> messageList = client.ReceiveBatch(100);
        foreach (BrokeredMessage message in messageList)
        {
            try
            {
                Console.WriteLine(message.GetBody<string>() + message.MessageId);

                message.Complete();
            }
            catch (Exception ex)
            {
                message.Abandon();
            }
        }

    client.Close();
    MessageBox.Show("Done");
  1. Using the above code, if I send 4 messages, then poll on the first run through I get the first message. On the second run through I get the other 3. I'm expecting to get all 4 at the same time. It seems to always return a singular value on the first poll then the rest on subsequent polls. (same result with 3 and 5 where I get n-1 of n messages sent on the second try and 1 message on the first try).

  2. If I have 0 messages to receive, the operation takes between ~30-60 seconds to get the messageList (that has a 0 count). I need this to return instantly.

  3. If I change the code to IEnumerable<BrokeredMessage> messageList = client.ReceiveBatch(100, new Timespan(0,0,0)); then issue #2 goes away because issue 1 still persists where I have to call the code twice to get all the messages.

I'm assuming that issue #2 is because of a default timeout value which I overwrite in #3 (though I find it confusing that if a message is there it immediately responds without waiting the default time). I am not sure why I never receive the full amount of messages in a single ReceiveBatch however.


回答1:


The way I got ReceiveBatch() to work properly was to do two things.

  1. Disable Partitioning in the Topic (I had to make a new topic for this because you can't toggle that after creation)
  2. Enable Batching on each subscription created like so:
  3. List item

SubscriptionDescription sd = new SubscriptionDescription(topicName, orgSubName); sd.EnableBatchedOperations = true;

After I did those two things, I was able to get the topics to work as intended using IEnumerable<BrokeredMessage> messageList = client.ReceiveBatch(100, new TimeSpan(0,0,0));




回答2:


I'm having a similar problem with an ASB Queue. I discovered that I could mitigate it somewhat by increasing the PrefetchCount on the client prior to receiving the batch:

SubscriptionClient client = SubscriptionClient.CreateFromConnectionString(connectionString, convoTopic, subName);

client.PrefetchCount = 100;

IEnumerable<BrokeredMessage> messageList = client.ReceiveBatch(100);

From the Azure Service Bus Best Practices for Performance Improvements Using Service Bus Brokered Messaging:

Prefetching enables the queue or subscription client to load additional messages from the service when it performs a receive operation.

...

When using the default lock expiration of 60 seconds, a good value for SubscriptionClient.PrefetchCount is 20 times the maximum processing rates of all receivers of the factory. For example, a factory creates 3 receivers, and each receiver can process up to 10 messages per second. The prefetch count should not exceed 20*3*10 = 600.

...

Prefetching messages increases the overall throughput for a queue or subscription because it reduces the overall number of message operations, or round trips. Fetching the first message, however, will take longer (due to the increased message size). Receiving prefetched messages will be faster because these messages have already been downloaded by the client.




回答3:


Just a few more pieces to the puzzle. I still couldn't get it to work even after Enable Batching and Disable Partitioning - I still had to do two ReceiveBatch calls. I did find however:

  • Restarting the Service Bus services (I am using Service Bus for Windows Server) cleared up the issue for me.
  • Doing a single RecieveBatch and taking no action (letting the message locks expire) and then doing another ReceiveBatch caused all of the messages to come through at the same time. (Doing an initial ReceiveBatch and calling Abandon on all of the messages didn't cause that behavior.)

So it appears to be some sort of corruption/bug in Service Bus's in-memory cache.



来源:https://stackoverflow.com/questions/31949698/odd-behavior-of-azure-service-bus-receivebatch

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!