Quelle est la meilleure pratique pour déplacer les messages d'une file d'attente de lettres mortes vers la file d'attente d'origine dans Amazon SQS?
Serait-ce
Ou existe-t-il un moyen plus simple?
En outre, AWS disposera-t-il éventuellement d'un outil dans la console pour déplacer les messages hors de la liste DLQ?
Cela ressemble à votre meilleure option. Il est possible que votre processus échoue après l'étape 2. Dans ce cas, vous finirez par copier le message deux fois, mais votre application devrait quand même gérer la remise des messages (ou ne pas s'en soucier).
Voici un petit hack. Ce n'est certainement pas la meilleure option ou recommandée.
Il n'est pas nécessaire de déplacer le message car il comportera de nombreux autres problèmes, tels que des messages en double, des scénarios de récupération, un message perdu, une vérification de déduplication, etc.
Voici la solution que nous avons mise en place -
En général, nous utilisons le DLQ pour les erreurs transitoires, pas pour les erreurs permanentes. Alors pris ci-dessous l'approche -
Lire le message de DLQ comme une file d'attente normale
AvantagesSuivez ensuite le même code que la file d'attente habituelle.
Plus fiable en cas d’abandon du travail ou d’arrêt du processus en cours de traitement (par exemple, instance tuée ou processus arrêté)
AvantagesÉtendez la visibilité des messages de sorte qu'aucun autre thread ne les traite.
AvantageSupprimez le message uniquement en cas d'erreur permanente ou de réussite.
Avantageici:
import boto3
import sys
import Queue
import threading
work_queue = Queue.Queue()
sqs = boto3.resource('sqs')
from_q_name = sys.argv[1]
to_q_name = sys.argv[2]
print("From: " + from_q_name + " To: " + to_q_name)
from_q = sqs.get_queue_by_name(QueueName=from_q_name)
to_q = sqs.get_queue_by_name(QueueName=to_q_name)
def process_queue():
while True:
messages = work_queue.get()
bodies = list()
for i in range(0, len(messages)):
bodies.append({'Id': str(i+1), 'MessageBody': messages[i].body})
to_q.send_messages(Entries=bodies)
for message in messages:
print("Coppied " + str(message.body))
message.delete()
for i in range(10):
t = threading.Thread(target=process_queue)
t.daemon = True
t.start()
while True:
messages = list()
for message in from_q.receive_messages(
MaxNumberOfMessages=10,
VisibilityTimeout=123,
WaitTimeSeconds=20):
messages.append(message)
work_queue.put(messages)
work_queue.join()
J'ai écrit un petit script python pour le faire, en utilisant boto3 lib:
conf = {
"sqs-access-key": "",
"sqs-secret-key": "",
"reader-sqs-queue": "",
"writer-sqs-queue": "",
"message-group-id": ""
}
import boto3
client = boto3.client(
'sqs',
aws_access_key_id = conf.get('sqs-access-key'),
aws_secret_access_key = conf.get('sqs-secret-key')
)
while True:
messages = client.receive_message(QueueUrl=conf['reader-sqs-queue'], MaxNumberOfMessages=10, WaitTimeSeconds=10)
if 'Messages' in messages:
for m in messages['Messages']:
print(m['Body'])
ret = client.send_message( QueueUrl=conf['writer-sqs-queue'], MessageBody=m['Body'], MessageGroupId=conf['message-group-id'])
print(ret)
client.delete_message(QueueUrl=conf['reader-sqs-queue'], ReceiptHandle=m['ReceiptHandle'])
else:
print('Queue is currently empty or messages are invisible')
break
vous pouvez obtenir ce script dans ce link
ce script peut en principe déplacer des messages entre des files d'attente arbitraires. et il supporte les files d'attente fifo ainsi que vous pouvez fournir le champ message_group_id
.
Il existe un autre moyen de réaliser cela sans écrire une seule ligne de code . Considérons que le nom actuel de votre file d'attente est SQS_Queue et que la DLQ pour ce nom est SQS_DLQ . Suivez maintenant ces étapes: