DEV Community

Marcos Belorio
Marcos Belorio

Posted on • Edited on

Erros comuns ao usar o AWS SQS

O Amazon Simple Queue Service (SQS) é um serviço de mensageria totalmente gerenciado e serverless, muito popular por ser simples, altamente escalável e robusto. A proposta desse artigo é trazer alguns erros comuns que devemos nos atentar ao utilizar o serviço.

Configurar o visibility timeout muito baixo

O visibility timeout determina por quanto tempo uma mensagem permanece indisponível após ser consumida. Se o consumidor não deletar a mensagem antes do término desse período, a mensagem retorna à fila para ser processada novamente.

Um erro comum é configurar o visibility timeout com um valor que não permita tempo suficiente para o consumidor processar a mensagem. Isso pode resultar em problemas como o processamento duplicado da mesma mensagem, já que o consumidor pode concluir o processamento, mas não conseguir deletar a mensagem antes que ela volte para a fila.

Solução

A AWS recomenda configurar o visibility timeout para ser três vezes maior que o tempo estimado de processamento da mensagem. Isso ajuda a cobrir cenários de exceção, como eventuais lentidões no processamento.

Configurar o retention period muito baixo

O retention period é usado para determinar o tempo de vida de uma mensagem na fila, uma vez expirado esse tempo, a mensagem é apagada, mesmo não tendo sido consumida.

Configurar o retention period de forma errada pode causar perda de mensagens na sua aplicação.

Solução

Defina um valor generoso para o retention period, lembrando que a AWS não cobra pelo armazenamento das mensagens no SQS. Além disso, é recomendável configurar o retention period máximo de 14 dias para filas DLQ (Dead-Letter Queues). Isso dá ao time de suporte tempo suficiente para identificar e resolver problemas relacionados a essas mensagens, permitindo o reprocessamento adequado.

Esperar que as mensagens sejam consumidas na mesma ordem que foram enviadas

O serviço SQS possui dois tipos de filas, o tipo standard e o tipo FIFO, o tipo standard possui um throughput maior mas não garante a ordem das mensagens, somente o tipo FIFO.

Solução

Se você precisa garantir a ordem do consumo das mensagens, então você deve utilizar a fila do tipo FIFO. Quando você envia uma mensagem para uma fila FIFO, você precisa fornecer um MessageGroupId, esse atributo garante a ordenação entre as mensagens de mesmo id. Lembrando que a fila FIFO não garante ordenação entre mensagens que possuem MessageGroupId diferentes.

Enviar/Consumir mensagens individualmente

O envio ou consumo de mensagens de forma individual pode impactar tanto a performance quanto o custo da aplicação, visto que a AWS cobra pela quantidade de requisições ao serviço do SQS.

Solução

A API do SQS permite o envio e o consumo de mensagens em batch, reduzindo o número de requisições ao serviço e, consequentemente, diminuindo os custos. Do ponto de vista de performance, realizar menos requisições com mais dados em cada uma delas tende a ser mais eficiente, pois reduz o número de viagens de ida e volta na rede.

Enviar mensagens em batch sem conhecer os limites da action SendMessageBatchCommand

Quando começamos a enviar mensagens em batch pro serviço do SQS, é importante considerar os limites da action SendMessageBatchCommand. Esta action limita o batch a 10 mensagens e o tamanho total da requisição a 256KB, note que o limite de tamanho se aplica à requisição total, não a cada mensagem individualmente. Se uma requisição exceder um desses limites, o batch inteiro de mensagens é recusado, gerando erro na sua aplicação.

Solução

Implemente uma lógica na sua aplicação ou utilize alguma lib que garanta o envio de até 10 mensagens e até 256kb por requisição.

Não tratar o sucesso parcial da action SendMessageBatchCommand

Outro ponto que traz um pouco mais de complexidade ao usar o envio de mensagens em batch é o fato de que a requisição pode retornar um sucesso parcial. Isso significa que, dentro de uma única requisição, algumas mensagens podem ser enviadas com sucesso, enquanto outras podem falhar. Se esse cenário não for tratado na aplicação, pode resultar em perda de mensagens.

Solução

Ao usar a action SendMessageBatchCommand, sua aplicação deve sempre verificar a resposta recebida. Se houver mensagens que não foram enviadas com sucesso, esse cenário deve ser tratado de maneira apropriada, como, por exemplo, tentando reenviar as mensagens falhas.

Lançar erros durante o consumo de mensagens em batch

Mais um cenário comum que pode resultar em perda de mensagens ou processamento duplicado é a falta de tratamento durante o consumo de mensagens em batch. Normalmente, o consumo de mensagens em batch é realizado dentro de um loop na aplicação, onde cada mensagem é processada individualmente. Como cada processamento pode lançar erros, é necessário que a aplicação esteja preparada para lidar com essas exceções, para não afetar o lote inteiro.

Solução

Em filas do tipo Standard onde a ordenação das mensagens não é relevante, se o processamento de uma mensagem resultar em erro, a aplicação deve permitir que as demais mensagens continuem sendo processadas. As mensagens não processadas devem ser devolvidas à fila para tentativas futuras de processamento. No entanto, para filas do tipo FIFO, onde a ordem das mensagens é importante, se uma mensagem falhar no processamento, a aplicação deve interromper o processamento imediatamente. Todas as mensagens não processadas devem ser devolvidas à fila para tentativas futuras de processamento, ou o lote inteiro pode ser devolvido caso a aplicação esteja preparada para lidar com o consumo duplicado de mensagens.

Não tratar duplicidade de mensagens

Por último, aplicações que utilizam mensageria devem estar preparados para um possível cenário de mensagens duplicadas, podendo causar inconsistência de dados.

Solução

Aplicar estratégias de idempotência durante o consumo de mensagens, seja diretamente na fila ou no momento da persistência dos dados. Aqui no meu blog eu escrevi como tratar Idempotência em filas do serviço AWS SQS.

Referências

SendMessageBatchCommand
What happens if SQS messages partially fail in SendMessageBatch?

Top comments (0)