1. Create Standard Queue With DLQ#
export AWS_REGION=ap-east-1
export QUEUE_NAME=dev-order-payment-capture
export DLQ_NAME=dev-order-payment-capture-dlqCreate DLQ:
aws sqs create-queue \
--region "$AWS_REGION" \
--queue-name "$DLQ_NAME" \
--attributes '{
"MessageRetentionPeriod": "1209600",
"ReceiveMessageWaitTimeSeconds": "20",
"SqsManagedSseEnabled": "true"
}'Get DLQ ARN:
export DLQ_URL=$(aws sqs get-queue-url \
--region "$AWS_REGION" \
--queue-name "$DLQ_NAME" \
--query 'QueueUrl' \
--output text)
export DLQ_ARN=$(aws sqs get-queue-attributes \
--region "$AWS_REGION" \
--queue-url "$DLQ_URL" \
--attribute-names QueueArn \
--query 'Attributes.QueueArn' \
--output text)Create source queue:
cat > /tmp/sqs-source-attributes.json <<EOF
{
"MessageRetentionPeriod": "345600",
"VisibilityTimeout": "120",
"ReceiveMessageWaitTimeSeconds": "20",
"SqsManagedSseEnabled": "true",
"RedrivePolicy": "{\"deadLetterTargetArn\":\"$DLQ_ARN\",\"maxReceiveCount\":\"5\"}"
}
EOF
aws sqs create-queue \
--region "$AWS_REGION" \
--queue-name "$QUEUE_NAME" \
--attributes file:///tmp/sqs-source-attributes.jsonGet queue URL:
export QUEUE_URL=$(aws sqs get-queue-url \
--region "$AWS_REGION" \
--queue-name "$QUEUE_NAME" \
--query 'QueueUrl' \
--output text)2. Send Message#
aws sqs send-message \
--region "$AWS_REGION" \
--queue-url "$QUEUE_URL" \
--message-body '{
"schema_version": 1,
"event_type": "payment.capture.requested",
"request_id": "req-123",
"order_id": "ord-1001",
"amount_cents": 1200
}' \
--message-attributes '{
"trace_id": {
"DataType": "String",
"StringValue": "trace-abc"
},
"schema_version": {
"DataType": "Number",
"StringValue": "1"
}
}'3. Receive And Delete#
Receive:
aws sqs receive-message \
--region "$AWS_REGION" \
--queue-url "$QUEUE_URL" \
--max-number-of-messages 1 \
--wait-time-seconds 20 \
--attribute-names ApproximateReceiveCount SentTimestamp \
--message-attribute-names AllDelete after successful processing:
export RECEIPT_HANDLE='<paste-receipt-handle-from-receive-message>'
aws sqs delete-message \
--region "$AWS_REGION" \
--queue-url "$QUEUE_URL" \
--receipt-handle "$RECEIPT_HANDLE"Extend visibility for long processing:
aws sqs change-message-visibility \
--region "$AWS_REGION" \
--queue-url "$QUEUE_URL" \
--receipt-handle "$RECEIPT_HANDLE" \
--visibility-timeout 3004. Create FIFO Queue#
aws sqs create-queue \
--region "$AWS_REGION" \
--queue-name dev-order-state.fifo \
--attributes '{
"FifoQueue": "true",
"ContentBasedDeduplication": "true",
"ReceiveMessageWaitTimeSeconds": "20",
"VisibilityTimeout": "120",
"SqsManagedSseEnabled": "true"
}'Send FIFO message:
export FIFO_URL=$(aws sqs get-queue-url \
--region "$AWS_REGION" \
--queue-name dev-order-state.fifo \
--query 'QueueUrl' \
--output text)
aws sqs send-message \
--region "$AWS_REGION" \
--queue-url "$FIFO_URL" \
--message-group-id "order-ord-1001" \
--message-deduplication-id "order-state-ord-1001-v7" \
--message-body '{
"schema_version": 1,
"event_type": "order.state.changed",
"order_id": "ord-1001",
"version": 7,
"status": "PAID"
}'5. Inspect Queue#
aws sqs get-queue-attributes \
--region "$AWS_REGION" \
--queue-url "$QUEUE_URL" \
--attribute-names Allaws cloudwatch get-metric-statistics \
--region "$AWS_REGION" \
--namespace AWS/SQS \
--metric-name ApproximateAgeOfOldestMessage \
--dimensions Name=QueueName,Value="$QUEUE_NAME" \
--start-time "$(date -u -v-30M +%FT%TZ)" \
--end-time "$(date -u +%FT%TZ)" \
--period 60 \
--statistics Maximum6. Cleanup#
aws sqs delete-queue \
--region "$AWS_REGION" \
--queue-url "$QUEUE_URL"
aws sqs delete-queue \
--region "$AWS_REGION" \
--queue-url "$DLQ_URL"7. Redrive Messages From DLQ After Fix#
aws sqs start-message-move-task \
--region "$AWS_REGION" \
--source-arn "$DLQ_ARN"redrive notes:
this moves messages from DLQ back to the configured source queue
use only after root cause is fixed
replay in controlled window
watch duplicate side effects and source queue age during replay