RabbitMQ
Tags: braziliandevs, microservices
Published: 2022-06-21 02:02:03

O RabbitMQ é um Message broker, ele faz o meio de campo entre a pessoa que envia a mensagem a pessoa q vai receber a mensagem. Ele implementa os protocolos AMQP, MQTT, STOMP e HTTP, sendo que o mais utilizado é o AMQP, que é baseado no TCP deixando o assim com uma velocidade muito rápida. Ele foi desenvolvido em Erlang, facilita o processo de desacoplamento entre os serviços pois ele que vai lidar com a comunicação entre esses serviços, ele é extremamente rápido e poderoso, além disso ele tem I/O por padrão diferente do Kafka que temos que implementar técnicas para isso. 

## Por baixo dos panos

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u5vds9ia8obzcoxau5w7.png) 

Temos um client e um server, e essa conexão acontece por padrão por TCP, que de inicio é um pouco lenta, mas para evitar esse processo toda vez que formos no conectar e consumir uma fila no RabbitMQ ele abre apenas uma conexão e dentro dessa conexão ele cria subconexões que são chamadas de channels. Evitando assim todo o processo de abertura de conexão, isso é chamado de multiplexing connection, todo channel aberto também é uma nova thread

## Funcionamento Básico

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dvtw44gprrlihej3q7g6.png)
 

Temos um Publisher que como o nome já diz é o cara que vai publicar a mensagem e o consumidor que é quem vai ler a mensagem. Porem o publisher não envia a mensagem diretamente para o consumidor, ele envia para uma exchange que pega a mensagem que o publisher mandou, processa a mensagem e descobre para qual fila a mensagem deveria ser enviada e ai envia a mensagem para essa fila, e então o consumidor fica lendo essa fila de mensagens 


## Tipos de Exchange

Em um sistema podemos ter n filas e n exchanges, sendo que n filas podem estar conectadas com n exchanges e n exchanges podem estar conectados com n filas

- Direct
A exchange manda a mensagem especificamente para uma determinada fila

- Fanout
Quando manda uma mensagem pra essa exchange ela envia essa mensagem para todas as filas ligadas a essa exchange

- Topic
Adicionamos algumas regras para dependendo do routing key ela encaminhar seguindo essa regra

- Headers
O header da mensagem determina em qual fila queremos que a mensagem seja entregue

### Direct Exchange

Na mensagem vamos especificar qual a routing Key da fila que queremos enviar a mensagem e então o exchange faz somente o processo de encaminhar a mensagem para a fila com o mesmo routing key

### Fanout Exchange

Nesse caso não passamos nenhuma routing key, enviamos apenas uma mensagem e essa mensagem vai ser replicada para todas as filas vinculadas a essa exchange

Muito útil por exemplo em um sistema de compras onde queremos informar a diversos sistemas que a compra ocorreu como o sistema de estoque, administrativo, logs, nota fiscal e etc... Basta conectarmos todos esses sistemas na mesma exchange que ela já encaminha a mensagem para todos

### Topic Exchange

Ele também funciona com as routing keys porem nesse caso as routing keys conseguem ter regras semelhantes a RegEx, e a exchange vai procurar quais as filas que dão match nessa RegEx


## Queues

As filas trabalham no padrão FIFO (First in First Out)

### Propriedades

1. Durable: Se ela deve ou não ser salva depois do restart do broker por padrão elas vem como duráveis
1. Auto-delete: Removida automaticamente quando o consumer se desconecta
1. Expiry: Define o tempo que não há mensagens ou clientes consumindo
1. Message TTL: Tempo de vida da mensagem
1. Max length ou bytes: Quantidade de mensagens que podem ir para uma fila ou o tamanho de bytes máximo permitido
1. Overflow: O que fazer quando a fila encher
  * Drop Head (remove a última)
  * Reject publish (não aceita novas mensagens)
1. Exclusive: Somente o channel que criou pode acessar

### Dead letter queues

Algumas mensagens não conseguem ser entregues por algum motivo. Essas mensagens são encaminhadas para uma exchange especifica que roteia elas para uma dead letter queue, e então elas podem ser consumidas e averiguadas posteriormente.

### Lazy queues

Quando o RabbitMQ chega no limite da memoria as mensagens passam a ser armazenadas em disco. Porem o ponto negativo é que exige um alto I/O, quando há muitas mensagens em uma fila por qualquer motivo. há a possibilidade de liberar a memória jogando algumas mensagens especificas para o disco


## Simulador 

Utilizei um [simulador](http://tryrabbitmq.com/) de RabbitMQ para testar os conceitos aprendidos 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nys9w7uivvdf78qw34ck.png)

## Confiabilidade

Como garantir que as mensagens não serão perdidas no meio do caminho? e que as mensagens puderam ser processadas corretamente pelos consumidores?

O RabbitMQ tem alguns recursos pensados para resolver essas situações:

1. Consumer acknowledgement: quando um consumer avisa que recebeu a mensagem
1. Publisher confirm: Todas as vezes que enviamos a mensagem o publisher informa que a imagem chegou até a exchange
1. Filas e mensagens duráveis / persistidas

### Consumer acknowledgement

Existem 3 tipos de consumer acnowledgement:

1. Basic.Ack
O consumer recebe a mensagem e informa que está tudo ok

1. Basic.Reject
Rejeita a mensagem fazendo ela voltar e ficar na fila novamente

1. Basic.Nack
É semelhante ao reject porem pode rejeitar mais de uma ao mesmo tempo

### Publisher confirms

A mensagem vai ter um id que vai ser do tipo int, quando o publisher enviar essa mensagem para a exchange, ela avisa para o publisher que recebeu a mensagem e passa o id, então o publisher fica sabendo que a mensagem foi recebida pela exchange. Porem se a exchange tiver algum problema ela vai retornar um Nack passando o id da mensagem que deu o problema para que o publisher saiba que aquela mensagem não foi publicada