Azure服务总线主题的带毒消息处理最佳实践

问题描述 投票:0回答:1

从Azure Service Bus处理有毒消息(使用时抛出异常)会导致循环,直到重试次数达到主题订阅的maxDeliveryCount设置为止。

  1. Azure Service总线添加的消息的SequenceNumber是否在每次失败的尝试中持续增加,直到达到maxDeliveryCount
  2. 设置maxDeliveryCount = 1,是处理有毒消息的最佳实践,以便消费者一旦失败就永远不会尝试两次处理消息
azure azureservicebus servicebus azure-servicebus-topics
1个回答
0
投票

最佳做法取决于您的应用程序和重试方法。

我大部分时间都注意到消息发送失败

  1. 从属服务不可用(Redis,SQL连接问题)

  2. 错误消息(消息没有必需的参数或某些值不正确)

  3. 处理代码问题(消息处理代码中的错误)

对于第一种和第三种情况,我创建了C#Web作业来运行和重新处理死信消息。

下面是我的代码

internal class Program
    {
        private static string connectionString = ConfigurationSettings.AppSettings["GroupAssetConnection"];
        private static string topicName = ConfigurationSettings.AppSettings["GroupAssetTopic"];
        private static string subscriptionName = ConfigurationSettings.AppSettings["GroupAssetSubscription"];
        private static string databaseEndPoint = ConfigurationSettings.AppSettings["DatabaseEndPoint"];
        private static string databaseKey = ConfigurationSettings.AppSettings["DatabaseKey"];
        private static string deadLetterQueuePath = "/$DeadLetterQueue";

        private static void Main(string[] args)
        {

            try
            {
                ReadDLQMessages(groupAssetSyncService, log);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                throw;
            }
            finally
            {
                documentClient.Dispose();
            }
            Console.WriteLine("All message read successfully from Deadletter queue");
            Console.ReadLine();
        }

        public static void ReadDLQMessages(IGroupAssetSyncService groupSyncService, ILog log)
        {
            int counter = 1;
            SubscriptionClient subscriptionClient = SubscriptionClient.CreateFromConnectionString(connectionString, topicName, subscriptionName + deadLetterQueuePath);
            while (true)
            {
                BrokeredMessage bmessgage = subscriptionClient.Receive(TimeSpan.FromMilliseconds(500));
                if (bmessgage != null)
                {
                    string message = new StreamReader(bmessgage.GetBody<Stream>(), Encoding.UTF8).ReadToEnd();
                    syncService.UpdateDataAsync(message).GetAwaiter().GetResult();
                    Console.WriteLine($"{counter} message Received");
                    counter++;
                    bmessgage.Complete();
                }
                else
                {
                    break;
                }
            }

            subscriptionClient.Close();
        }
    }

在第二种情况下,我们手动验证死信消息(自定义UI /服务总线浏览,有时纠正消息数据,有时清除消息并清除队列。

我不推荐maxDeliveryCount=1。如果发生某些网络/连接问题,则内置重试将处理并从队列中清除。当我在财务应用程序中工作时,我将maxDeliveryCount=5保留下来,而在IoT应用程序中则为maxDeliveryCount=3

如果您正在批量阅读邮件,则如果发生任何邮件错误,将重新处理完整的批次。

SequenceNumber该序列号可以作为唯一标识符而被信任,因为它是由中央和中立机构而不是由客户端分配的。它也代表了真正的到达顺序,并且比时间戳更精确,因为时间戳在极端的消息速率下可能没有足够高的分辨率,并且在以下情况下可能会受到时钟偏斜的影响(但是最小)节点之间的代理所有权过渡。

© www.soinside.com 2019 - 2024. All rights reserved.