Pular para conteúdo

AWS SQS - Fila de Mensagens

O que é este Node?

O AWS SQS é o node responsável por gerenciar filas de mensagens na Amazon SQS (Simple Queue Service), permitindo enviar, receber, deletar mensagens e criar filas.

Por que este Node existe?

Sistemas distribuídos precisam comunicação assíncrona e confiável. O AWS SQS existe para:

  1. Desacoplamento: Separar componentes do sistema para escalabilidade independente
  2. Buffer de mensagens: Proteger contra picos de tráfego e sobrecarga
  3. Processamento assíncrono: Executar tarefas em background sem bloquear o flow
  4. Garantia de entrega: Mensagens não se perdem mesmo se o consumidor estiver offline
  5. Integração com AWS: Conectar com Lambda, SNS, EventBridge e outros serviços

Como funciona internamente?

Quando o AWS SQS é executado, o sistema:

  1. Autentica usando accessKeyId e secretAccessKey
  2. Cria cliente SQS configurado para região especificada
  3. Executa operação conforme especificado (send, receive, delete, create)
  4. Processa resposta da AWS
  5. Retorna resultado com messageId, mensagens ou status
  6. Se erro: Lança exceção com detalhes

Código interno (aws-executors.service.ts:94-156):

async executeAWSSQS(data: any, variables: Record<string, any>): Promise<any> {
  try {
    this.logger.log('📨 [AWS SQS] Executing operation');

    const sqs = new AWS.SQS({
      accessKeyId: data.accessKeyId,
      secretAccessKey: data.secretAccessKey,
      region: data.region,
    });

    switch (data.operation) {
      case 'sendMessage':
        const sendResult = await sqs.sendMessage({
          QueueUrl: data.queueUrl,
          MessageBody: JSON.stringify(data.messageBody),
          MessageAttributes: data.messageAttributes,
          DelaySeconds: data.delaySeconds,
        }).promise();
        return {
          success: true,
          messageId: sendResult.MessageId,
        };

      case 'receiveMessages':
        const receiveResult = await sqs.receiveMessage({
          QueueUrl: data.queueUrl,
          MaxNumberOfMessages: data.maxMessages || 10,
          WaitTimeSeconds: data.waitTimeSeconds || 0,
          VisibilityTimeout: data.visibilityTimeout,
        }).promise();
        return {
          success: true,
          messages: receiveResult.Messages || [],
        };

      case 'deleteMessage':
        await sqs.deleteMessage({
          QueueUrl: data.queueUrl,
          ReceiptHandle: data.receiptHandle,
        }).promise();
        return {
          success: true,
          message: 'Message deleted successfully',
        };

      case 'createQueue':
        const createResult = await sqs.createQueue({
          QueueName: data.queueName,
          Attributes: data.attributes,
        }).promise();
        return {
          success: true,
          queueUrl: createResult.QueueUrl,
        };

      default:
        throw new Error(`Unknown SQS operation: ${data.operation}`);
    }
  } catch (error) {
    this.logger.error('AWS SQS execution error:', error);
    throw error;
  }
}

Quando você DEVE usar este Node?

Use AWS SQS quando precisar de comunicação assíncrona confiável:

Casos de uso:

  1. Processamento em lote: Enviar tarefas para workers processarem
  2. Webhooks: Receber notificações de sistemas externos
  3. Integração com Lambda: Disparar funções serverless
  4. Microserviços: Comunicar entre serviços desacoplados
  5. Rate limiting: Controlar taxa de processamento de tarefas
  6. Retry automático: Sistema tenta reprocessar mensagens com falha

Quando NÃO usar AWS SQS:

  • Comunicação em tempo real: Use WebSockets ou SNS
  • Pub/Sub broadcasting: Use SNS (SQS é 1-para-1)
  • Eventos ordenados globalmente: Use Kinesis
  • Armazenamento permanente: Use DynamoDB ou S3

Parâmetros Detalhados

accessKeyId (string, obrigatório)

O que é: Chave de acesso AWS IAM para autenticação.

Segurança: NUNCA exponha em código! Use variáveis de ambiente.

secretAccessKey (string, obrigatório)

O que é: Chave secreta AWS IAM correspondente ao accessKeyId.

Segurança: NUNCA exponha em código! Use variáveis de ambiente.

region (string, obrigatório)

O que é: Região AWS onde a fila está localizada.

Exemplos: us-east-1, us-west-2, sa-east-1 (São Paulo)

operation (string, obrigatório)

O que é: Operação a ser executada na fila.

Valores possíveis: - sendMessage: Enviar mensagem para fila - receiveMessages: Receber mensagens da fila - deleteMessage: Deletar mensagem processada - createQueue: Criar nova fila

queueUrl (string, obrigatório para send/receive/delete)

O que é: URL completa da fila SQS.

Formato: https://sqs.{region}.amazonaws.com/{account-id}/{queue-name}

Flow completo para testar sendMessage:

{
  "name": "Teste AWS SQS - Send Message",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "variable_1",
      "type": "variable",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Dados da Mensagem",
        "parameters": {
          "assignments": [
            {
              "variable": "pedido",
              "value": {
                "orderId": "123",
                "customer": "José Roberto",
                "total": 250.00
              }
            }
          ]
        }
      }
    },
    {
      "id": "sqs_1",
      "type": "aws_sqs",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Enviar para Fila",
        "parameters": {
          "accessKeyId": "{{AWS_ACCESS_KEY}}",
          "secretAccessKey": "{{AWS_SECRET_KEY}}",
          "region": "sa-east-1",
          "operation": "sendMessage",
          "queueUrl": "https://sqs.sa-east-1.amazonaws.com/123456789/pedidos",
          "messageBody": "{{pedido}}",
          "delaySeconds": 0
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "✅ Pedido enviado para fila!\nMessage ID: {{messageId}}"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 900, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "variable_1" },
    { "source": "variable_1", "target": "sqs_1" },
    { "source": "sqs_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: A mensagem é enviada para fila e você recebe o MessageId único.

messageBody (any, obrigatório para sendMessage)

O que é: Conteúdo da mensagem a ser enviada. Pode ser string, objeto ou array.

Conversão: Automaticamente convertido para JSON string.

maxMessages (number, opcional para receiveMessages)

O que é: Número máximo de mensagens a receber em uma chamada.

Padrão: 10

Limite AWS: 1 a 10 mensagens

Flow completo para testar receiveMessages:

{
  "name": "Teste AWS SQS - Receive Messages",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "sqs_1",
      "type": "aws_sqs",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Receber Mensagens",
        "parameters": {
          "accessKeyId": "{{AWS_ACCESS_KEY}}",
          "secretAccessKey": "{{AWS_SECRET_KEY}}",
          "region": "sa-east-1",
          "operation": "receiveMessages",
          "queueUrl": "https://sqs.sa-east-1.amazonaws.com/123456789/pedidos",
          "maxMessages": 5,
          "waitTimeSeconds": 10
        }
      }
    },
    {
      "id": "condition_1",
      "type": "condition",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Tem mensagens?",
        "parameters": {
          "conditions": [
            {
              "variable": "messages",
              "operator": "exists",
              "nextNode": "message_1"
            }
          ],
          "defaultNextNode": "message_2"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 700, "y": 50 },
      "data": {
        "label": "Com Mensagens",
        "parameters": {
          "message": "📬 Recebidas {{messages.length}} mensagens da fila!"
        }
      }
    },
    {
      "id": "message_2",
      "type": "message",
      "position": { "x": 700, "y": 150 },
      "data": {
        "label": "Fila Vazia",
        "parameters": {
          "message": "📭 Nenhuma mensagem na fila."
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 900, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "sqs_1" },
    { "source": "sqs_1", "target": "condition_1" },
    { "source": "message_1", "target": "end_1" },
    { "source": "message_2", "target": "end_1" }
  ]
}

Teste: Recebe até 5 mensagens da fila ou retorna array vazio se não houver.

waitTimeSeconds (number, opcional para receiveMessages)

O que é: Tempo de espera (long polling) por mensagens novas.

Padrão: 0 (short polling - retorna imediatamente)

Recomendado: 10-20 segundos (reduz custos e melhora performance)

receiptHandle (string, obrigatório para deleteMessage)

O que é: Token único recebido ao buscar mensagem, necessário para deletá-la.

Origem: Vem no campo ReceiptHandle do receiveMessages

Flow completo para testar deleteMessage:

{
  "name": "Teste AWS SQS - Delete Message",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "sqs_receive",
      "type": "aws_sqs",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Receber Mensagem",
        "parameters": {
          "accessKeyId": "{{AWS_ACCESS_KEY}}",
          "secretAccessKey": "{{AWS_SECRET_KEY}}",
          "region": "sa-east-1",
          "operation": "receiveMessages",
          "queueUrl": "https://sqs.sa-east-1.amazonaws.com/123456789/pedidos",
          "maxMessages": 1,
          "waitTimeSeconds": 5
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Processar",
        "parameters": {
          "message": "⚙️ Processando pedido: {{messages[0].Body}}"
        }
      }
    },
    {
      "id": "sqs_delete",
      "type": "aws_sqs",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Deletar da Fila",
        "parameters": {
          "accessKeyId": "{{AWS_ACCESS_KEY}}",
          "secretAccessKey": "{{AWS_SECRET_KEY}}",
          "region": "sa-east-1",
          "operation": "deleteMessage",
          "queueUrl": "https://sqs.sa-east-1.amazonaws.com/123456789/pedidos",
          "receiptHandle": "{{messages[0].ReceiptHandle}}"
        }
      }
    },
    {
      "id": "message_2",
      "type": "message",
      "position": { "x": 900, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "✅ Mensagem processada e removida da fila!"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1100, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "sqs_receive" },
    { "source": "sqs_receive", "target": "message_1" },
    { "source": "message_1", "target": "sqs_delete" },
    { "source": "sqs_delete", "target": "message_2" },
    { "source": "message_2", "target": "end_1" }
  ]
}

Teste: Recebe, processa e deleta mensagem da fila.

queueName (string, obrigatório para createQueue)

O que é: Nome da nova fila a ser criada.

Regras: Apenas letras, números, hífens e underscores. Máximo 80 caracteres.

Parâmetros

Campo Tipo Obrigatório Descrição
accessKeyId string Sim Chave de acesso AWS IAM
secretAccessKey string Sim Chave secreta AWS IAM
region string Sim Região AWS (ex: sa-east-1)
operation string Sim sendMessage, receiveMessages, deleteMessage, createQueue
queueUrl string Condicional URL da fila (exceto createQueue)
messageBody any Condicional Conteúdo da mensagem (sendMessage)
maxMessages number Não Máximo de mensagens a receber (padrão: 10)
waitTimeSeconds number Não Long polling em segundos (padrão: 0)
receiptHandle string Condicional Token para deletar mensagem
queueName string Condicional Nome da fila (createQueue)
delaySeconds number Não Atraso antes de mensagem ficar visível (0-900s)
visibilityTimeout number Não Tempo que mensagem fica invisível após recebimento
messageAttributes object Não Metadados customizados

Exemplo 1: Sistema de Processamento de Pedidos

Objetivo: Enviar pedidos para fila de processamento assíncrono

JSON para Importar

{
  "name": "AWS SQS - Sistema de Pedidos",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "input_1",
      "type": "input",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "ID do Pedido",
        "parameters": {
          "message": "Digite o ID do pedido:",
          "variable": "pedidoId"
        }
      }
    },
    {
      "id": "variable_1",
      "type": "variable",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Criar Pedido",
        "parameters": {
          "assignments": [
            {
              "variable": "pedidoCompleto",
              "value": {
                "orderId": "{{pedidoId}}",
                "timestamp": "{{$now}}",
                "status": "pending",
                "customer": "{{phone}}"
              }
            }
          ]
        }
      }
    },
    {
      "id": "sqs_1",
      "type": "aws_sqs",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Enviar para Fila",
        "parameters": {
          "accessKeyId": "{{AWS_ACCESS_KEY}}",
          "secretAccessKey": "{{AWS_SECRET_KEY}}",
          "region": "sa-east-1",
          "operation": "sendMessage",
          "queueUrl": "https://sqs.sa-east-1.amazonaws.com/123456789/pedidos",
          "messageBody": "{{pedidoCompleto}}"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 900, "y": 100 },
      "data": {
        "label": "Confirmação",
        "parameters": {
          "message": "✅ Pedido {{pedidoId}} enviado para processamento!\n\n📨 Message ID: {{messageId}}\n\nSeu pedido será processado em breve."
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1100, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "input_1" },
    { "source": "input_1", "target": "variable_1" },
    { "source": "variable_1", "target": "sqs_1" },
    { "source": "sqs_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Saída esperada:

Sistema: Digite o ID do pedido:
Usuário: PED-12345
Sistema: ✅ Pedido PED-12345 enviado para processamento!

📨 Message ID: abc123-def456-ghi789

Seu pedido será processado em breve.

Exemplo 2: Worker Processando Fila

Objetivo: Buscar e processar mensagens da fila continuamente

JSON para Importar

{
  "name": "AWS SQS - Worker Processor",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "sqs_receive",
      "type": "aws_sqs",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Buscar Mensagens",
        "parameters": {
          "accessKeyId": "{{AWS_ACCESS_KEY}}",
          "secretAccessKey": "{{AWS_SECRET_KEY}}",
          "region": "sa-east-1",
          "operation": "receiveMessages",
          "queueUrl": "https://sqs.sa-east-1.amazonaws.com/123456789/pedidos",
          "maxMessages": 10,
          "waitTimeSeconds": 20,
          "visibilityTimeout": 30
        }
      }
    },
    {
      "id": "condition_1",
      "type": "condition",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Tem mensagens?",
        "parameters": {
          "conditions": [
            {
              "variable": "messages.length",
              "operator": ">",
              "value": 0,
              "nextNode": "loop_1"
            }
          ],
          "defaultNextNode": "message_empty"
        }
      }
    },
    {
      "id": "loop_1",
      "type": "loop",
      "position": { "x": 700, "y": 50 },
      "data": {
        "label": "Processar Cada",
        "parameters": {
          "array": "{{messages}}",
          "itemVariable": "message",
          "indexVariable": "index"
        }
      }
    },
    {
      "id": "message_process",
      "type": "message",
      "position": { "x": 900, "y": 50 },
      "data": {
        "label": "Processar",
        "parameters": {
          "message": "⚙️ Processando: {{message.Body}}"
        }
      }
    },
    {
      "id": "sqs_delete",
      "type": "aws_sqs",
      "position": { "x": 1100, "y": 50 },
      "data": {
        "label": "Remover da Fila",
        "parameters": {
          "accessKeyId": "{{AWS_ACCESS_KEY}}",
          "secretAccessKey": "{{AWS_SECRET_KEY}}",
          "region": "sa-east-1",
          "operation": "deleteMessage",
          "queueUrl": "https://sqs.sa-east-1.amazonaws.com/123456789/pedidos",
          "receiptHandle": "{{message.ReceiptHandle}}"
        }
      }
    },
    {
      "id": "message_success",
      "type": "message",
      "position": { "x": 1300, "y": 50 },
      "data": {
        "label": "Sucesso",
        "parameters": {
          "message": "✅ {{messages.length}} mensagens processadas!"
        }
      }
    },
    {
      "id": "message_empty",
      "type": "message",
      "position": { "x": 700, "y": 150 },
      "data": {
        "label": "Fila Vazia",
        "parameters": {
          "message": "📭 Fila vazia. Aguardando novas mensagens..."
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1500, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "sqs_receive" },
    { "source": "sqs_receive", "target": "condition_1" },
    { "source": "loop_1", "target": "message_process" },
    { "source": "message_process", "target": "sqs_delete" },
    { "source": "sqs_delete", "target": "message_success" },
    { "source": "message_success", "target": "end_1" },
    { "source": "message_empty", "target": "end_1" }
  ]
}

Saída esperada:

Sistema: ⚙️ Processando: {"orderId":"PED-12345","status":"pending"}
Sistema: ⚙️ Processando: {"orderId":"PED-67890","status":"pending"}
Sistema: ✅ 2 mensagens processadas!

Resposta do Node

SendMessage:

{
  "success": true,
  "messageId": "abc123-def456-ghi789"
}

ReceiveMessages:

{
  "success": true,
  "messages": [
    {
      "MessageId": "abc123",
      "ReceiptHandle": "token-xyz",
      "Body": "{\"orderId\":\"123\"}",
      "Attributes": {},
      "MessageAttributes": {}
    }
  ]
}

DeleteMessage:

{
  "success": true,
  "message": "Message deleted successfully"
}

CreateQueue:

{
  "success": true,
  "queueUrl": "https://sqs.sa-east-1.amazonaws.com/123456789/minha-fila"
}

Boas Práticas

SIM:

  • Use long polling (waitTimeSeconds: 10-20) para reduzir custos
  • SEMPRE delete mensagens após processamento bem-sucedido
  • Use visibility timeout adequado ao tempo de processamento
  • Armazene credenciais AWS em variáveis de ambiente
  • Use Dead Letter Queue (DLQ) para mensagens com falha
  • Implemente idempotência no processamento
  • Monitore métricas da fila (ApproximateNumberOfMessages)

NÃO:

  • Não exponha credenciais AWS em código
  • Não processe mensagens sem deletá-las depois
  • Não use visibility timeout muito curto (causa reprocessamento)
  • Não envie mensagens > 256KB (use S3 para payloads grandes)
  • Não ignore erros de envio/recebimento

Dicas

💡 Custo: Long polling reduz custos em até 90% vs short polling 💡 Segurança: Use IAM roles ao invés de access keys quando possível 💡 Performance: Use batch operations para processar múltiplas mensagens 💡 Monitoring: CloudWatch Alarms para alertar sobre filas cheias 💡 Retry: Mensagens não deletadas voltam para fila após visibility timeout 💡 FIFO: Use fila FIFO (.fifo) se ordem for crítica 💡 DLQ: Configure Dead Letter Queue para mensagens problemáticas

Próximo Node

AWS SNS - Notificações pub/sub → AWS DYNAMODB - Banco de dados NoSQL → AWS LAMBDA - Executar funções serverless