Introdução ao AWS SNS/SQS
O AWS SNS (Simple Notification Service) e o SQS (Simple Queue Service) formam uma estrutura de mensageria robusta para sistemas distribuídos.
- SNS: Suporta mensageria pub/sub (entrega para múltiplos consumidores).
- SQS: Oferece filas para processamento confiável de mensagens. Combinar esses serviços com o Brighter — uma biblioteca .NET para manipulação de comandos/consultas — permite construir sistemas resilientes e desacoplados em larga escala.
Este guia demonstra como configurar o Brighter para publicar eventos via SNS e consumi-los via SQS, com exemplos de código e soluções para limitações atuais.
Requisitos
- .NET 8+
- Pacotes NuGet no projeto:
- Paramore.Brighter.MessagingGateway.AWSSQS: Integração com SNS/SQS.
- Paramore.Brighter.ServiceActivator.Extensions.DependencyInjection: Ponte para serviços AWS.
- Paramore.Brighter.ServiceActivator.Extensions.Hosting: Hospedagem do Brighter como serviço em segundo plano.
- Serilog.AspNetCore: (opcional, mas recomendado para logs estruturados).
Recapitulação do Brighter
Antes de configurar o AWS SNS/SQS, relembre conceitos essenciais do Brighter:
Mensagens (Comandos/Eventos)
Defina mensagens usando IRequest
:
public class Greeting : Event(Guid.NewGuid())
{
public string Name { get; set; } = string.Empty;
}
-
Comandos: Operações com um único destinatário (ex:
EnviarEmail
). -
Eventos: Notificações para múltiplos consumidores (ex:
PedidoEnviado
).
Mapeador de Mensagens
Converte mensagens do Brighter para objetos da aplicação:
public class GreetingMapper : IAmAMessageMapper<Greeting>
{
public Message MapToMessage(Greeting request)
{
var header = new MessageHeader
{
Id = request.Id,
TimeStamp = DateTime.UtcNow,
Topic = "greeting.topic", // Tópico SNS de destino
MessageType = MessageType.MT_EVENT
};
var body = new MessageBody(JsonSerializer.Serialize(request));
return new Message(header, body);
}
public Greeting MapToRequest(Message message)
{
return JsonSerializer.Deserialize<Greeting>(message.Body.Bytes)!;
}
}
Manipulador de Requisições
Processa mensagens recebidas:
public class GreetingHandler(ILogger<GreetingHandler> logger) : RequestHandler<Greeting>
{
public override Greeting Handle(Greeting command)
{
logger.LogInformation("Olá, {Name}!", command.Name);
return base.Handle(command);
}
}
Configurando Brighter com AWS SNS/SQS
Conexão com AWS
Defina as configurações de autenticação:
var connection = new AWSMessagingGatewayConnection(
FallbackCredentialsFactory.GetCredentials(), // Credenciais AWS
AWSConfigs.RegionEndpoint, // Ex: RegionEndpoint.USEast1
opt => { /* Configurações avançadas do cliente AWS */ }
);
Consumidor SQS
Inscreva uma fila SQS em um tópico SNS:
.AddServiceActivator(opt =>
{
opt.Subscriptions = [
new SqsSubscription<Greeting>(
new SubscriptionName("greeting-subscription"), // Nome da inscrição
new ChannelName("greeting-queue"), // Nome da fila SQS
new RoutingKey("greeting.topic").ToValidSNSTopicName(), // Tópico SNS
bufferSize: 2 // Número de mensagens processadas simultaneamente
)
];
opt.ChannelFactory = new ChannelFactory(connection);
})
Produtor SNS
Publique eventos no SNS:
.UseExternalBus(new SnsProducerRegistryFactory(connection, new[]
{
new SnsPublication
{
Topic = new RoutingKey("greeting.topic".ToValidSNSTopicName()),
MakeChannels = OnMissingChannel.Create // Cria o tópico se não existir
}
}).Create());
Limitações Conhecidas (Brighter v9)
- Dependência Obrigatória do SNS: Todas as mensagens passam pelo SNS, mesmo para casos de uso direto do SQS.
- Sem Suporte a FIFO: Filas/tópicos FIFO (para processamento ordenado) não são suportados na v9.
- Compatibilidade com LocalStack: Configurações personalizadas (ex: endpoints LocalStack) podem não se propagar para todos os componentes.
Boa notícia: A versão Brighter v10 (em desenvolvimento) resolverá essas limitações.
Melhores Práticas
Validar Nome do Tópico SNS
Use .ToValidSNSTopicName()
para garantir nomes compatíveis com o AWS:
new RoutingKey("greeting.topic".ToValidSNSTopicName())
Configurar Filas de Cartas Mortas (DLQ)
Melhore a tolerância a falhas definindo uma DLQ:
new SqsSubscription<Greeting>(
subscriptionName: new SubscriptionName("greeting-subscription"),
channelName: new ChannelName("greeting-queue"),
routingKey: new RoutingKey("greeting.topic").ToValidSNSTopicName(),
bufferSize: 2,
redrivePolicy: new RedrivePolicy(
deadLetterQueueName: "greeting-dead", // Nome da DLQ
maxReceiveCount: 3 // Limite de tentativas
)
)
Conclusão
A integração do Brighter com AWS SNS/SQS combina a simplicidade da biblioteca com a escalabilidade da infraestrutura da AWS. Apesar das limitações da v9, os recursos principais permitem:
- Arquitetura Desacoplada: Produtores e consumidores evoluem independentemente.
- Resiliência: SQS armazena mensagens durante picos de tráfego.
- Escalabilidade: SNS/SQS se adaptam automaticamente à carga.
Referência
Código completo: Repositório GitHub