天蓝色队列中的消息消失

Posted

技术标签:

【中文标题】天蓝色队列中的消息消失【英文标题】:Messages in azure queue vanish 【发布时间】:2021-01-26 12:06:59 【问题描述】:

我希望这里有人能对我现在遇到两次的问题有所了解。 我有一个创建发票的 ERP 系统,当这些发票准备好发送时,我通过 cron 计划作业将它们传输到我们的发票系统。当它们从发票系统发送给最终客户时,它会触发一个 webhook 到一个 azure http 触发器函数,该函数将消息(invoiceId)放入队列中。然后我有一个队列触发器,它可以提取这些信息并更新我们的 ERP 系统,这样发票就不能再更改了。这在 90% 的情况下都非常有效。

上周,我们向发票系统发送了 12 张发票,我们的簿记员将这些发票发送给了客户。 今天早上检查时,其中 2 个没有在我们的 ERP 系统中更新为“已发送”状态。 所以我检查了队列触发器,可以看到有问题的两张发票没有调用(在函数 -> 监视器下)。所以我检查了毒物队列,它既不存在也不存在于真正的队列中。最后,我检查了 Http 触发器调用,我可以看到有两个发票的调用有问题,并且我有一个日志,它在其中将已正确记录且没有错误的消息排入队列。

所以让我感到奇怪的是,对于其他 10 张发票,这一切都很好,没有任何遗漏。但是对于这两个队列消息似乎消失了。有人有什么想法吗?

分享我添加到队列和更新我们的 ERP 系统的两个功能。

HttpTrigger

[FunctionName(nameof(InvoiceBooked))]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)]
            HttpRequest req, ILogger log)
        
            try
            
                log.LogInformation("Invoice Booked from VS. C# HTTP trigger function processed a request.");
                string invoiceBookedId = req.Query["invoiceId"];
                log.LogInformation($"Invoice Booked. RequestBody: invoiceBookedId");

                if (string.IsNullOrEmpty(invoiceBookedId))
                
                    log.LogError("Invoice Booked. Query was empty");
                    return new BadRequestResult();
                

                // Get the connection string from app settings
                var storageAccountName = System.Environment.GetEnvironmentVariable("StorageAccountName", EnvironmentVariableTarget.Process);
                var storageAccountKey = System.Environment.GetEnvironmentVariable("StorageAccountKey", EnvironmentVariableTarget.Process);
                string connectionString =
                    $"DefaultEndpointsProtocol=https;AccountName=storageAccountName;AccountKey=storageAccountKey;EndpointSuffix=core.windows.net";

                // Instantiate a QueueClient which will be used to create and manipulate the queue
                var queueClient = new QueueClient(connectionString, AzureConstants.InvoiceBookedQueueName);

                // Create the queue
                await queueClient.CreateIfNotExistsAsync();
                log.LogInformation($"Invoice Booked. Enqueuing message: invoiceBookedId");
                if (await queueClient.ExistsAsync())
                
                    var messageBase64 = System.Convert.ToBase64String(
                        System.Text.Encoding.UTF8.GetBytes(invoiceBookedId));

                    // Send a message to the queue
                    await queueClient.SendMessageAsync(messageBase64);

                    log.LogInformation($"Invoice Booked. Message enqueued: invoiceBookedId");
                
            
            catch (Exception e)
            
                log.LogError(e, "Invoice Booked. Error when enqueueing booked invoice");
            

            return (ActionResult)new OkResult();
        

队列触发器

[FunctionName(nameof(InvoiceBookedQueueTrigger))]
        public static void Run([QueueTrigger(AzureConstants.InvoiceBookedQueueName, Connection = "QueueStorage")]string queueItem, ILogger log)
        
            log.LogInformation($"InvoiceBookedQueueTrigger. C# Queue trigger function processed: queueItem");

            var erpService = new ERPService(log, System.Environment.GetEnvironmentVariable("APIKey", EnvironmentVariableTarget.Process));

            int.TryParse(queueItem, out var invoiceId);

            log.LogInformation($"invoiceId is: invoiceId");

            var success = erpService.SetInvoiceBooked(invoiceId);

            if(!success)
                throw new WebException("There was a problem updating the invoice in erp");
            
        

我似乎找到了一些额外的信息。出于某种原因,作业主机有时会停止。我今天注意到,我手动输入了一些已经消失的 id,有些通过了,但一个又消失了。在跟踪日志中,我可以看到,就在它应该获取队列项目的时间,作业主机被停止了。令我感到奇怪的是,消息已出队,根本没有关于此的日志。如果我在消息启动时将消息放入队列中,一切正常。有人有任何想法吗?我已添加日志供您查看

日志文件可以在这里下载:https://1drv.ms/t/s!AotNYJ6EYJBWiRysY93fP2ODdFVX

【问题讨论】:

我似乎找到了一些额外的信息。出于某种原因,作业主机有时会停止。我今天注意到,我手动输入了一些已经消失的 id,有些通过了,但一个又消失了。在跟踪日志中,我可以看到,就在它应该获取队列项目的时间,作业主机被停止了。令我感到奇怪的是,消息已出队,根本没有关于此的日志。如果我在消息启动时将消息放入队列中,一切正常。有人有任何想法吗?我已添加日志供您查看 【参考方案1】:

与 Microsoft 支持一起,我发现在 Consumption Plan 上运行时会出现一些问题,即它可能会以某种方式丢失队列项目。 MS 支持无法解释该问题,但更改为应用服务计划已完全解决了该问题。

【讨论】:

以上是关于天蓝色队列中的消息消失的主要内容,如果未能解决你的问题,请参考以下文章

天蓝色队列如何重试失败的消息?

kafka使用- 概念理解

Vue Snackbar 消息条队列显示,依次动画消失的实现

从 Array 推送到 Azure 队列覆盖消息?[node.JS]

vue背景透明度消失

更长触发 lambda 的 SQS 消息