我是否使用AWS SQS FIFO队列正确发送和接收消息?

时间:2020-08-07 06:27:44

标签: amazon-web-services amazon-sqs

我正在研究AWS SQS FIFO队列并构建一些原型。但是,我在掌握如何提取已发送的特定消息方面遇到困难。 现在有几个问题:

  1. 我知道通过ReceiveMessageAsync调用会返回邮件列表。我是否应该遍历此列表,并将MessageId属性与原始发送邮件的属性匹配?
  2. 如果队列中有未处理的消息列表,比如说15,而我发送了一条新消息,那么当从队列中删除至少6条消息时,我的消息将仅以ReceiveMessageAsync返回吗? / li>

当前,在我的原型中,我执行一个SendMessageAsync请求,然后立即执行一个ReceiveMessageAsync以获取已处理的消息。我在这里遍历接收到的messageIds列表,以获取我的消息,对消息执行一些逻辑,然后请求从队列中删除该消息。这种逻辑正确吗?

var sqsClient = new AmazonSQSClient(RegionEndpoint.EUWest1);
            var sendQueueUrl = $"{ConfigurationManager.AppSettings["AWSServer"]}{ConfigurationManager.AppSettings["SQSSend"]}";
            var deduplicationId = "fc1e026d-4a04-4cdf-b0b0-16bc78dde19c"; //Guid.NewGuid().ToString();

        var sqsMessageRequest = new SendMessageRequest
        {
            QueueUrl = sendQueueUrl,
            MessageGroupId = "testGroup",
            MessageDeduplicationId = deduplicationId,
            MessageBody = "{\"message\":\"hello\"}"
        };
        try
        {
            var sendMessageResponse = await sqsClient.SendMessageAsync(sqsMessageRequest);

            var receiveQueueUrl = $"{ConfigurationManager.AppSettings["AWSServer"]}{ConfigurationManager.AppSettings["SQSReceive"]}";
            var receiveMessageRequest = new ReceiveMessageRequest
            {
                AttributeNames = { "All" },
                MaxNumberOfMessages = 10,
                MessageAttributeNames = { "All" },
                QueueUrl = receiveQueueUrl,
                WaitTimeSeconds = 20
            };

            bool messagesFound = false;

            while (!messagesFound)
            {
                var receiveMessageResponse = await sqsClient.ReceiveMessageAsync(receiveMessageRequest);

                if (receiveMessageResponse.HttpStatusCode != System.Net.HttpStatusCode.OK)
                    Console.WriteLine("Failed request to receive message\n");
                else
                {
                    foreach (var message in receiveMessageResponse.Messages)
                    {
                        if (message.MessageId != sendMessageResponse.MessageId)
                            continue;

                        messagesFound = true;
                        /*process message further and delete afterwards*/
                        var deleteMessageRequest = new DeleteMessageRequest($"{ConfigurationManager.AppSettings["AWSServer"]}{ConfigurationManager.AppSettings["SQSReceive"]}", message.ReceiptHandle);
                        var deleteMessageResponse = await sqsClient.DeleteMessageAsync(deleteMessageRequest);
                    }
                }
            }
        }
        catch (Exception ex)
        {
            throw new Exception("SendMessageAsync: " + ex.Message);
        }
        finally
        {
            sqsClient.Dispose();
        }

1 个答案:

答案 0 :(得分:0)

如果这是您的目标,那么对FIFO队列中的SQS而言,遍历队列以查找特定项目将是低效率的。

实际上,您最好看看Virtual Queues,它将提供一种使用SQS执行发送和接收的一对一映射的方法。

通过使用此功能,您可以为特定消息定义虚拟队列,使用方将能够处理所有消息(或从技术上讲是特定虚拟队列中的使用方)。

鉴于FIFO和标准SQS队列,您将需要处理队列中的所有消息,一次最多可处理10条消息。这样一来,尝试查找您的特定消息的效率就会大大降低。

相关问题