在 Amazon SQS 中使用死信队列 - 适用于 Ruby 的 AWS 开发工具包
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

在 Amazon SQS 中使用死信队列

Amazon SQS 为死信队列提供支持。死信队列是其他(源)队列可将其作为无法成功处理的消息的目标的队列。您可以搁置和隔离死信队列中的这些消息以确定其处理失败的原因。有关死信队列的更多信息,请参阅使用 Amazon SQS 死信队列

在此示例中,您结合使用AWS SDK for Ruby和 Amazon SQS 来:

  1. 通过使用 Aws::SQS::Client#create_queue 来创建表示死信队列的队列。

  2. 通过使用 Aws::SQS::Client#set_queue_attributes 来将死信队列与现有队列相关联。

  3. 通过使用 Aws::SQS::Client#send_message 来向现有队列发送消息。

  4. 通过使用 Aws::SQS::QueuePoller 来轮询队列。

  5. 通过使用 Aws::SQS::Client#receive_message 来接收死信队列中的消息。

Prerequisites

在运行示例代码之前,您需要安装并配置AWS SDK for Ruby,如下所述:

您还需要使用 AWS 管理控制台创建现有队列 my-queue

注意

为简单起见,此示例代码没有演示 Aws::SQS::Client#add_permission。在真实场景中,您应始终限制对 SendMessage、ReceiveMessage、DeleteMessage 和 DeleteQueue 等操作的访问。 否则可能会导致信息泄露、拒绝服务或将消息注入您的队列中。

Example

# Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # This file is licensed under the Apache License, Version 2.0 (the "License"). # You may not use this file except in compliance with the License. A copy of the # License is located at # # http://aws.amazon.com/apache2.0/ # # This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS # OF ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. # Demonstrates how to: # 1. Create a queue representing a dead letter queue. # 2. Associate the dead letter queue with an existing queue. require 'aws-sdk-sqs' # v2: require 'aws-sdk' # Uncomment for Windows. # Aws.use_bundled_cert! sqs = Aws::SQS::Client.new(region: 'us-east-1') # Create a queue representing a dead letter queue. dead_letter_queue_name = "dead-letter-queue" sqs.create_queue({ queue_name: dead_letter_queue_name }) # Get the dead letter queue's URL and ARN, so that you can associate it with an existing queue. dead_letter_queue_url = sqs.get_queue_url(queue_name: dead_letter_queue_name).queue_url dead_letter_queue_arn = sqs.get_queue_attributes({ queue_url: dead_letter_queue_url, attribute_names: ["QueueArn"] }).attributes["QueueArn"] # Associate the dead letter queue with an existing queue. begin queue_name = "my-queue" queue_url = sqs.get_queue_url(queue_name: queue_name).queue_url # Use a redrive policy to specify the dead letter queue and its behavior. redrive_policy = { "maxReceiveCount" => "5", # After the queue receives the same message 5 times, send that message to the dead letter queue. "deadLetterTargetArn" => dead_letter_queue_arn }.to_json sqs.set_queue_attributes({ queue_url: queue_url, attributes: { "RedrivePolicy" => redrive_policy } }) rescue Aws::SQS::Errors::NonExistentQueue puts "A queue named '#{queue_name}' does not exist." exit(false) end # Send a message to the queue. puts "Sending a message..." sqs.send_message({ queue_url: queue_url, message_body: "I hope I get moved to the dead letter queue." }) 30.downto(0) do |i| print "\rWaiting #{i} second(s) for sent message to be receivable..." sleep(1) end puts "\n" poller = Aws::SQS::QueuePoller.new(queue_url) # Receive 5 messages max and stop polling after 20 seconds of no received messages. poller.poll(max_number_of_messages:5, idle_timeout: 20) do |messages| messages.each do |msg| puts "Received message ID: #{msg.message_id}" end end # Check to see if Amazon SQS moved the message to the dead letter queue. receive_message_result = sqs.receive_message({ queue_url: dead_letter_queue_url, max_number_of_messages: 1 }) if receive_message_result.messages.count > 0 puts "\n#{receive_message_result.messages[0].body}" else puts "\nNo messages received." end