Azure ServiceBus主题无法交付到订阅

时间:2016-10-24 15:54:04

标签: azure azureservicebus servicebus azure-servicebus-topics

我在使用Azure Service Bus实例时遇到了一个非常令人沮丧的问题。具体来说,我有一个名为"命令"经过一段时间后,它将停止正确地将消息代理到其订阅。我观察到以下行为让我处于目前困惑状态:

  1. 这只会在主题存在一段时间后才会发生,通常是一夜之间。一切都将在晚上工作,但是当我早上回来时,主题已经停止运作,唯一的解决方案似乎是删除并重新创建它。

  2. 如下图所示,主题似乎正在接收消息,因为我在发送后没有收到任何例外,并且"有效消息计数" "字节大小"关于该主题的属性确实增加。它只是不会将消息发送到订阅:enter image description here

  3. 我认为也许我的订阅中的过滤器搞砸了,所以为了测试这个,我删除了这些订阅,并使用默认过滤器通过资源管理器创建了一个新订阅。完成此操作后,我通过该主题发送了一些新消息,但新订阅仍未收到这些消息。

  4. 我在服务总线上运行了其他主题(例如"事件"在上图中),但他们似乎没有表现出相同的行为。它们以相同的方式配置,但运行得很好。

  5. 我对任何可能导致这种奇怪行为的理论持开放态度。如果有助于解决此问题,我很乐意提供其他信息。

    代码块:

    创建主题:

    private async Task<bool> CreateTopicAsync(NamespaceManager namespaceManager, string topicName, CancellationToken cancel, TimeSpan maxWaitTime)
            {
                var retVal = false;
                var maxTimeToCreateTopic = DateTime.UtcNow + maxWaitTime;
    
                while (!cancel.IsCancellationRequested && DateTime.UtcNow < maxTimeToCreateTopic)
                {
                    try
                    {
                        await namespaceManager.CreateTopicAsync(new TopicDescription(topicName)
                        {
                            EnableBatchedOperations = true,
                            EnableFilteringMessagesBeforePublishing = true
                        });
                        retVal = true;
                        break;
                    }
                    catch (Exception ex)
                    {
                        LogError("Exception thrown when creating topic: {0}", ex);
                    }
    
                    if (!retVal)
                    {
                        LogWarning("Topic still does not exist, pausing and then retrying creation.");
                        await Task.Delay(_delayMs);
                    }
                }
    
                return retVal;
            }
    

    创建订阅:

    private async Task<bool> CreateSubscriptionAsync(NamespaceManager namespaceManager, string topicName, string subscriptionName, string filter, CancellationToken cancel, TimeSpan maxWaitTime)
            {
                var retVal = false;
                var maxTimeToCreateSubscription = DateTime.UtcNow + maxWaitTime;
    
                while (!cancel.IsCancellationRequested && DateTime.UtcNow < maxTimeToCreateSubscription)
                {
                    try
                    {
                        if (string.IsNullOrEmpty(filter))
                        {
                            namespaceManager.CreateSubscription(topicName, subscriptionName);
                        }
                        else
                        {
                            namespaceManager.CreateSubscription(topicName, subscriptionName, new SqlFilter(filter));
                        }
                        retVal = true;
                        break;
                    }
                    catch (Exception ex)
                    {
                        LogError("Exception thrown when creating subscription: {0}", ex);
                    }
    
                    LogWarning("Subscription still does not exist, pausing and then retrying creation.");
                    await Task.Delay(_delayMs);
                }
    
                return retVal;
            }
    

    发送消息至主题:

    BrokeredMessage brokeredMessage = null;
                        try
                        {
                            var type = nextMessage.GetType().AssemblyQualifiedName;
                            var jsonString = JsonConvert.SerializeObject(nextMessage);
                            var jsonStream = jsonString.ToStream();
    
                            brokeredMessage = new BrokeredMessage(jsonStream, true);
                            brokeredMessage.Properties["__messageType__"] = type;
                            if (nextData.Properties != null && nextData.Properties.Count > 0)
                            {
                                foreach (var prop in nextData.Properties)
                                {
                                    brokeredMessage.Properties.Add(prop.Key, prop.Value);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            LogError("Exception thrown when creating brokered message: {0}", ex);
    
                            brokeredMessage = null;
                        }
    
                        if (brokeredMessage != null)
                        {
                            var messageSentSuccessfully = false;
                            try
                            {
                                await client.SendAsync(brokeredMessage);
                                numConsecutiveFailures = 0;
                                messageSentSuccessfully = true;
                            }
                            catch (Exception ex)
                            {
                                numConsecutiveFailures++;
                                LogError("Exception thrown from SendAsync: {0}. Fail count is {1}.", ex, numConsecutiveFailures);
                                await Task.Delay(_delayMs);
                            }
                        }
    

    主题客户端中的传递仅使用TopicClient.CreateFromConnectionString方法创建。

    从订阅接收消息:

    private async Task ReceiveLoopAsync(SubscriptionClient client, CancellationToken cancel, TimeSpan maxReceiveWaitTime)
            {
                var numConsecutiveFailures = 0;
                var maxConsecutiveFailures = 5;
    
                while (!cancel.IsCancellationRequested && numConsecutiveFailures < maxConsecutiveFailures)
                {
                    BrokeredMessage newMsg = null;
    
                    try
                    {
                        newMsg = await client.ReceiveAsync(maxReceiveWaitTime);
                        numConsecutiveFailures = 0;
                    }
                    catch (Exception ex)
                    {
                        numConsecutiveFailures++;
                        LogError("Exception thrown from ReceiveAsync: {0}. Fail count is {1}.", ex, numConsecutiveFailures);
                        await Task.Delay(_delayMs);
                    }
    
                    // newMsg will be null if there were no messages to process after the allotted timeout expired.
                    if (newMsg != null)
                    {
                        // Just a function call.
                        _onMessageReceived?.Invoke(newMsg);
                    }
    
                    //LogDebug("Bottom of Receive");
                }
    
                //LogDebug("Exit Receive");
            }
    

    订阅客户端中的传递仅使用SubscriptionClient.CreateFromConnectionString方法创建。

0 个答案:

没有答案