loading...
Cover image for AWS SQS/SNS | Parte 4 | Afinal, o que são as Dead Letter Queue?

AWS SQS/SNS | Parte 4 | Afinal, o que são as Dead Letter Queue?

mchdax profile image Mayara Machado Updated on ・5 min read

Esse texto faz parte de uma série sobre a utilização da AWS SQS e SNS em uma aplicação python, sugiro a leitura dos textos anteriores para maior entendimento do processo.

Introdução

Esta é a parte final de uma série de 4 textos onde eu falo sobre como fazer uso das filas e tópicos disponibilizados pelos serviços SQS e SNS da AWS. Hoje iremos conhecer uma pouco sobre filas que servem para envio de mensagens mortas, iremos ver quais são algumas das possíveis causas de uma mensagem morta e como podemos preparar nosso serviço SQS para lidar com essas mensagens nos casos de erros. Ao final, iremos ver como podemos implementar uma Dead Letter Queue utilizando python e a lib Boto3 que é a SDK da AWS para python.

O que são Dead Letter Queue ou Fila de Mensagens Mortas

De modo geral, quando um serviço está processando uma mensagem da fila e tem esse processamento interrompido por motivos de erro ou até mesmo de instabilidade do serviço, esta mensagem se torna uma mensagem morta. Durante essa ocorrência é muito possível que o serviço perca a mensagem, ou até mesmo que ela seja corrompida e portanto perca-se o acompanhamento de quais mensagens conseguiram de fato serem consumidas e processadas. Nesse cenário, surgem as Dead Letter Queue que ,a grosso modo, são filas que armazenam as mensagens mortas.

Quando uma mensagem morre durante algum erro no processamento, a fila principal é capaz de redirecionar esta mensagem para a Dead Letter Queue vinculada a fila principal. As filas principais não precisam obrigatoriamente ter uma fila de mensagens mortas, ainda que seja uma configuração recomendada, e as filas de mensagens mortas não são criadas automaticamente pela AWS SQS. Para atribuirmos uma Dead Letter Queue a uma fila principal, devemos criar uma política de redirecionamento de mensagens na fila principal e atribuir o vínculo desta a uma segunda fila que irá agir como a fila de mensagens mortas para a fila principal.

Existem outras causas que podem resultar no envio de mensagens para uma Dead Letter Queue, uma delas ocorre quando a fila principal recebe uma mensagem mais vezes do que o limite definido no atributo maxReceiveCount da fila principal. Por exemplo, em filas normais é possível que mais de uma cópia da mensagem seja entregue na fila, nesse caso se temos o maxReceiveCount da fila principal  definido como 3 e recebermos uma mensagem 4 vezes, e suas cópias não forem excluídas, essa mensagem será enviada para a Dead Letter Queue configurada.

O grande benefício de uma Dead Letter Queue é poder obter conhecimento sobre o comportamento inexperado da aplicação ao tentar processar a mensagem. É possível definir um alarme para informar quando uma mensagem morta chega na fila, além disso, é possível depurar a mensagem para identificar problemas no envio e/ou recebimento de mensagens, assim como também é possível com auxílio de log identificar qual exceção está causando o redirecionamento daquela mensagem.

Condições para ter uma Dead Letter Queue

É possível ter várias filas principais e que todas elas apontem para uma mesma fila de mensagens mortas, desse modo, a quantidade de para das filas irá depender bastante da definição da arquitetura do seu projeto. Porém você deve se atentar para duas questões, a fila de mensagens mortas de uma fila tipo FIFO também deve ser uma fila FIFO e as filas principais e suas respectivas filas de mensagens mortas devem estar na mesma região, assim como serem criadas com a mesma conta.

No primeiro caso, devemos lembrar que a ordem de envio é muito importante em uma fila do tipo FIFO, e uma fila Dead Letter Queue  do tipo padrão não irá manter a ordem das mensagens mesmo que a fila principal de onde se origina a mensagem seja uma do tipo FIFO. Para o segundo caso , é uma determinação da AWS e portanto é necessário prestar atenção a esse detalhe na hora de monstar a estrutura de filas do seu projeto.

Por fim, outro detalhe a ter em mente é que todas as mensagens tem um tempo de expiração nas filas. Quando criamos uma fila é possível configurar o tempo padrão da vida de uma mensagem na fila, por default a AWS configura o período de permanência da mensagem por 4 dias, porém esse valor é totalmente configurável. Quando uma mensagem é redirecionada para uma fila de mensagens morta, ela não terá o contador do seu tempo de permanência reiniciado para a nova fila. Por exemplo, se uma mensagem é encaminhada para a fila de mensagens morta no seu terceiro dia de vida, e esta fila de mensagens morta possui uma definição de retenção de mensagens de 4 dia, a fila irá excluir essa mensagem após 1 dia, pois seu tempo de vida chegou ao limite do definido no tempo de retenção da Dead Letter Queue.

Implementando

Para implementarmos uma Dead Letter Queue, utilizaremos o conhecimento já adquirido anteriormente que é criar uma fila padrão, no entanto, o ponto de atenção na hora de criar essa fila é justamente o tempo de retenção da mensagem a ser definido. No exemplo desenvolvido, eu defini 6 dias em segundos (o Boto3 solicita que esses atributos sejam definidos em segundos) pois o tempo de renteção da minha fila principal é de 4 dias.

Para atribuir uma fila como Dead Letter Queue a uma fila padrão, devemos criar uma política de redirecionamento chamada RedrivePolicy e atribuir o código ARN da fila que será a nossa Dead Letter Queue. No código de exemplo eu montei a código ARN com base nas minhas informações pessoais da conta AWS, só exemplificando para vocês um outro método de obter o código ARN de uma fila.

import boto3, json

class DeadLetterQueue:

    def __init__(self, main_queue_url):
        self.main_queue_url = main_queue_url
        self.sqs_client = boto3.client(
                            'sqs', 
                            region_name='us-east-1'
                        )

    def __create_dead_letter_queue(self, queue_name):
        '''
            Create a dead letter.
        '''
        dead_letter_queue = self.sqs_client.create_queue(
             QueueName = ,
             Attributes={
                    "MessageRetentionPeriod" : "518400"  # 6 dias
                }
            )

        return dead_letter_queue


    def add_dead_letter_queue(self, queue_name, region, aws_id):

             # criar a fila para ser a Dead Letter Queue
             self.__create_dead_letter_queue(queue_name)

             # politica de redirecionamento para a fila recém criada
        redrive_policy = {
            "deadLetterTargetArn" : (f"arn:aws:sqs:{region}:{aws_id}:{queue_name}"),
            "maxReceiveCount" : "10"
        }

             # atualização da fila principal para atribuição da política de redirecionamento
        self.sqs_client.set_queue_attributes(
            QueueUrl= self.main_queue_url,
            Attributes={
            'RedrivePolicy' : json.dumps(redrive_policy)
            }
        )

        return True

Conclusão

Bom pessoal, com isso nós encerramos a série sobre como iniciar a utilizar as filas e tópicos disponibilizadas pelos serviços SQS e SNS da Amazon Web Services. Foi muito bom interessante ter tido essa experiência, e esses serviços se mostraram muito interessantes para uso como solução de comunicação para serviços em arquiteturas de Microserviços ou até mesmo uma arquitetura de Serviços. Obrigada por terem acompanhado até aqui, e vejo vocês na próxima.

Lembrando que o código completo poderá ser visualizado aqui.

Posted on by:

mchdax profile

Mayara Machado

@mchdax

I'm very passionate about programming and currently I do it mostly using python. I'm a pythonist.

Discussion

pic
Editor guide