fbpx
Filas exclusivas e autodelete
Publicado em: terça-feira, 15 de ago de 2023
Tags: RabbitMQ

Nem sempre as demandas exigem filas que durem aos restarts da sua aplicação. Há casos de uso significativos em que você quer que a fila nasça com a instância da sua aplicação e morra junto com ela.

Embora seja um conceito trivial, em mais de 10 anos usando RabbitMQ, essa foi a primeira vez que tive de fato essa a necessidade de adotar essa abordagem.

Filas Exclusivas

Exclusividade é uma das configurações possíveis para uma fila.

Essa configuração afeta o consumo da fila.

Uma fila exclusiva só pode ser consumida na conexão que a criou.

Ou seja, nenhuma outra conexão pode manipular (limpar, ou consumir) a fila.

Filas auto-delete

Auto-delete é também uma propriedade da fila, definida na criação da fila. Ela determina que quando o último consumidor for desconectado, ou quando o model for fechado, a fila será apagada (deletada fisicamente).

Ponto importante aqui é que caso haja uma política de dead-letter, ela se aplica também à exclusão da fila.

Caso de uso

Recentemente implementei um caso de uso de chat, onde cada instância do serviço (um container docker em um POD no Kubernetes) desse serviço pode ter várias conexões WebSocket conectadas a ele.

Cada conexão WebSocket representa um usuário em uma aplicação desktop, conectada a uma sala.

Após sairmos do Kafka e irmos para o RabbitMQ adotei uma solução com filas Exclusivas e Autodelete para que cada POD tenha sua própria fila, seguindo o mesmo tempo de vida do POD.

Quando o POD nasce, a fila nasce, quando o POD morre, a fila morre junto.

Somente o POD pode consumir a própria fila.

Esse desenho foi inspirado nas esteiras inteligentes de centros de distribuição.

As exchanges estão lá para entregar as mensagens nos POD’s interessados em cada sala. É assim que o POD recebe mensagens de uma das N salas onde tem usuários conectados.

Ciclo de Vida

Criação do Pod e sua Fila

Quando o POD é criado, sua fila exclusiva e autodelete é criada ao mesmo tempo, ainda no processo de inicialização do POD.

Até que o primeiro usuário se conecte, nenhuma mensagem é encaminhada para essa fila. Consequentemente, nenhuma mensagem é recebida no POD, mas ele continua escutando a sua fila.

Quando o usuário se conecta

Uma vez que o POD recebe a primeira conexão WebSocket, parâmetros dessa conexão definem em qual sala o usuário deseja se conectar.

Na lógica do serviço temos um Manager Singleton,
O Manager possui Virtual Rooms.
Uma Virtual Room possui conexões WebSockets (ConnectedClients).

Quando o usuário se conecta via WebSocket, o Manager identifica se a sala na qual o usuário está tentando se conectar já existe naquele POD. Caso não exista, ele cria uma Virtual Room e coloca a conexão WebSocket nela.

Quando uma sala é criada

Ao criar a sala, um bind entre a fila do POD e a Exchange de dispatch é criada para que o POD possa receber mensagens daquela determinada sala. A routing key do bind, é o ID da Sala.
É assim que a fila começa a receber mensagens daquela sala, e consequentemente o POD também.

O caminho de volta

Uma vez que o POD recebe uma mensagem vinda da sua fila, o Manager recebe a mensagem e busca a Virtual Room da qual a mensagem pertence. Repassa a mensagem para ela.

A Virtual Room ao receber a mensagem, envia para todos os WebSockets conectados a ela (inclusive para o próprio sender, caso ele esteja na lista) assim a mensagem chega à aplicação desktop.

Capacidades dessa arquitetura

Outros usuários podem se conectar à mesma sala, através do mesmo POD ou de outros PODs. Isso permite que a escala horizontal aconteça e que não tenhamos problemas com limitações de conexões de um pod, limitando a quantidade de usuários de uma sala.

A arquitetura permite:

  • Um número indefinido de salas
  • Um número indefinido de usuários por sala (embora na maior parte do tempo são apenas 2)
  • Um número indefinido de usuários ativos simultaneamente.

As limitações estão na quantidade de hardware que queremos empenhar nisso.

Uma nova conexão, quando estabelecida em um POD que já possui a sala, só coloca a conexão na sala existente, não precisando de outra tarefa. Afinal, o bind entre a exchange e a fila já foi criado com a criação da sala virtual.

Quando a última conexão WebSocket é fechada em uma sala, o Manager trata de encerrar a vida da sala naquele POD, isso significa também remover bind da exchange com a fila, fazendo com que a fila não mais receba mensagens daquela sala.

Dessa forma, quem publica mensagens apenas informa para qual sala está enviando, e o fluxo acontece dinamicamente.

Uma parte que não citei é que o fluxo conta com outras exchanges, uma dedicada à persistência, que possui uma única fila e diversos consumidores, processo padrão.

Conclusão

Foram necessários 10 anos para esbarrar em um problema que merecesse filas exclusivas e auto-delete.

O fato de não ser comum, está relacionado a, na maioria das vezes, usarmos o RabbitMQ para distribuir tarefas entre diversos consumidores.

Esse cenário, onde cada instância tem sua própria fila, não chegam a ser excepcionais, apenas são mais raros.

E só são avançados porque exigem conceitos disruptivos, e fundamentos sólidos.

Se você acha “esquisito”, “errado” deletar filas.
E tem a sensação de que está
deletando uma tabela em um banco de dados,
relaxa, é disruptivo para todo mundo no início.

Com o tempo você entende que estamos diante da versatilidade desse tipo de solução, e que aplicações de infraestrutura, e chat é uma delas, tendem a se beneficiar mais desses recursos.

O mais importante, se você está começando, é saber que existe e saber o que esperar, ou melhor: entender com precisão como se comporta.

Um dia, quando aparecer o problema, você terá a solução.

Grande abraço!

Você pediu e agora virou curso. Mensageria .NET é minha formação de especialista em RabbitMQ com .NET, onde ensino RabbitMQ do básico, cada fundamento, cada detalhe, ao avançado.

Onde você vai sair do zero absoluto e vai conseguir criar, projetar e corrigir soluções .NET com RabbitMQ.

Além de contar mais 3 outros bonus incríveis para ajudar todos que precisam de um up na carreira.

RabbitMQ Newsletter

Novidades e ofertas de conteúdo exclusivo e único no Brasil.

Hoje com orgulho somos referência quando se fala em RabbitMQ com .NET.

São quase 10 anos usando RabbitMQ em projetos .NET com C#, implantando, convencendo times e mostrando o caminho para aslcançar sos 5 benefícios.

Após centenas de pedidos, criei um curso dedicado aos profissionais .NET. 

Aqui nessa newsletter eu te entrego promoções e links especiais! Cola aqui, tem muita coisa legal!

Luiz Carlos Faria

Meu primeiro contato com RabbitMQ foi em 2013.

Eu estava sozinho na definição de uma arquitetura para a reestruturação de uma integração enquanto meu time estava ocupado com o dia-a-dia.

Naquela época eu precisava de apenas 1 ou 2 recursos que o RabbitMQ entregava.

Nas primeiras semanas e meses em produção pude perceber coisas que não estavam escritas em lugar algum, benefícios e formas de uso das quais poderiam resolver anos de frustração.

Desde então RabbitMQ tem sido meu aliado na restruturação de projetos dos mais variados.

E por mais simples que seja, ainda é possível, 10 anos depois, gerar surpresas com novas abordagens que geram novos benefícios.

7 dias

É tudo que precisa para sair do zero, à produção!

Com conforto, com segurança, e com apoio.

Desde que você já seja um desenvolvedor profissional.

Se você quer entregar mais Disponibilidade, Eficiência, Resiliência, Confiabilidade e/ou Escalabilidade, em projetos .NET, aqui é o seu lugar.

0 comentários

Enviar um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.

Lives

Fique de olho nas lives

Fique de olho nas lives no meu canal do Youtube, no Canal .NET e nos Grupos do Facebook e Instagram.

Aceleradores

Existem diversas formas de viabilizar o suporte ao teu projeto. Seja com os treinamentos, consultoria, mentorias em grupo.