Diferenças do AMQP 1.0 para as versões anteriores

Em uma arquitetura de microsserviços, é importante entender as principais vantagens e desvantagens das versões desse protocolo de mensageria

Definindo AMQP e o contextualizando na arquitetura de microsserviços

O Advanced Message Queuing Protocol é um dos protocolos existentes para a comunicação de serviços através de mensageria.

O protocolo tem um simples objetivo: definir a mecânica da transferência binária de mensagens, de maneira segura, confiável e eficiente entre duas partes.

Em uma arquitetura de microsserviços, o mais comum é que interfaces de usuário e o restante do mundo se comuniquem com os seus serviços através de REST/HTTP. Isso gera uma certa dependência entre o consumidor e o server, o que é aceitável nesse cenário. Entretanto, os serviços precisam ser independentes entre si. Se o serviço A depende de B diretamente, e B apresenta problemas e para de funcionar, logo teremos dois serviços indisponíveis. Portanto, começa a ficar complicado quando os serviços necessitam comunicar entre si.

A estratégia que está sendo adotada pelo mercado em geral para resolver esse problema é a utilização de Message Brokers, que aceitam alguns protocolos, dentre os quais se encontra o AMQP. Neste caso, todos os microsserviços sabem apenas sobre a existência desse hub de mensagens e não se conectam diretamente com os demais.

Como regra geral simplificada, podemos associar da seguinte maneira (Mesmo que nem sempre seja verdade…):

  • REST/HTTP: Comunicação síncrona, interdependente.
  • Node de Mensagens/AMQP: Comunicação assíncrona e centralizada.

Alguns Message Brokers que utilizam AMQP:

  • RabbitMQ
  • ActiveMQ
  • Apache Kafka
  • Azure Service Bus
  • AmazonMQ

“Novidades” da versão 1.0

Primeira “novidade”: não é o mesmo protocolo das versões anteriores. Simplesmente isso. Como mudar de AngularJS para Angular 2+…

O mais relevante é o fato de que AMQP 1.0 tem um maior foco nas definições para as camadas de mensageria, conexão e segurança. Todas as tentativas de definir um modelo de broker foram removidas.

O protocolo não é mais vinculado a nenhum tipo de topologia de aplicação. Na prática, isso significa o seguinte:

1 Minuto de silêncio para nosso velho amigo

Quem trabalhou com RabbitMQ (Que tem suporte vitalício à versão 0.9.x) ou outro Broker nessa versão, deve ter estudado e implementado trocas de mensagens que tinham as Exchanges como peça principal.

Pois é… Estes não existem mais e, como consequência, “Bindings”, “RoutingKeys” e outras propriedades, referentes às Exchanges, também foram descontinuadas.

Apesar disso, é possível obter os mesmos comportamentos de outras maneiras (Continue rolando pra baixo!).

Transporte

Rede AMQP

A rede AMQP é um conjunto de Containers, Nodes e Links.

  • Container: Contém Nodes. Podem ser: aplicações, Brokers etc.
  • Node: Qualquer entidade endereçável (Ex: Queue, tópic…)
  • Links: Conectam Nodes

Links são unidirecionais para transferência da mensagem. A direção contrária está preparada para receber o “Ack”. Destructive Links removem a mensagem da origem, enquanto Non-Destructive Links mantém a mensagem na origem e apenas a “copia” para o destino.

Cada link pode ter filtros que verificam se a mensagem pode trafegar através dele

Sessões e Conexão

Links existem em uma sessão.

Ela fornece uma maneira de realizar uma conversação bidirecional e sequencial. E pertence, por sua vez, à uma conexão.

As conexões costumam ser realizadas através de TCP ou SCTP. A segurança nessa comunicação é feita através de TLS/SSL e SASL Authentication.

Emulando comportamento das Exchanges

Conforme prometido acima, aqui apresento diagramas comparativos, de como atingir determinados objetos na versão 0.9 (acima) e na 1.0 (abaixo).

Fanout

Direct

Topic

Mensagem

Essas são as camadas de uma mensagem trafegada através do AMQP

Bare Message Core é imutável desde o sender até o último receiver, enquanto Annotated Message pode ser alterado por intermediários.

Abaixo encontramos um exemplo de como um JSON é trafegado nesse protocolo. É facilmente mapeado “from/to”.

É possível declarar e trafegar tipos primitivos de tamanho fixo (Como: Boolean, Bytes, Int, Char, UUID…), primitivos de tamanho variável (Como: Strings), e tipos compostos. No último caso, os nodes envolvidos devem ter conhecimento da estrutura desse tipo (que provavelmente será mapeado para um objeto, dependendo da linguagem).

Padrão Request/Response

Apesar do funcionamento assíncrono ser o principal foco na arquitetura de microsserviços, é possível fazer com que os Nodes comuniquem entre si simulando a comunicação síncrona. Funciona da seguinte maneira:

  • Uma fila única de requests por server.
  • Uma fila temporária de response por client.
  • Propriedade “reply-to” define o node dinâmico da resposta.
  • Propriedade “CorrelationId” define qual a mensagem associada à resposta.

Já era possível atingir algo parecido nas versões anteriores. As principais diferenças aqui são:

  • É preciso criar “Paired Links” dentro de uma seção: SenderLink e ReceiverLink.
  • Lidar com a hierarquia Connection -> Session -> Link.
  • Possibilidade de criar “Sources” dinâmicos, para a criação das filas temporárias exemplificadas no diagrama acima.

O RabbitMQ no meio de tudo isso

O RabbitMQ é atualmente o Broker mais utilizado em produção no mundo. Ele provém suporte completo para a versão 0.9.x e cumpre a promessa de mantê-lo vitalício. Existe um plugin que pode ser habilitado para que suporte a versão 1.0, entretanto apresenta limitações.

Abaixo se encontram as duas que considero como as mais problemáticas:

  • Não há suporte para Filters nos Links. Isso quer dizer que não é possível trabalhar com Tópicos.
  • Não há suporte para Dynamic Source. Isso significa que, no padrão request/response explicado acima, as filas não poderiam ser temporárias. Um dos problemas disso é o fato da necessidade de refatoração ao migrar de um outro Broker para o Rabbit.

Veja mais sobre o Plugin RabbitMQ 1.0

Principais Bibliotecas para AMQP 1.0

Considerações Finais sobre a escolha da melhor versão

Por que optar pela 0.9?

Ainda existem brokers que trabalham em versões anteriores. Na verdade, o broker mais utilizado no mundo em produção é um deles (RabbitMQ). Existe a promessa de sempre manter suporte à essa versão, então pode usar sem medo.

Em ambiente Cloud, costuma ser mais barato gerenciar uma máquina com um broker instalado do que utilizar o próprio serviço oferecido pelo fornecedor. Ou seja, podemos subir o RabbitMQ na VM e continuar utilizando 0.9.

Por que optar pela 1.0?

É o padrão internacional aprovado pela ISO e IEC como ISO/IEC 19464:2014. Todas as versões anteriores são consideradas como draft.

Os principais Cloud Vendors estão fornecendo serviços de broker através dessa versão.

Continue estudando

Agora te deixo nas mãos de quem sabe mais sobre o assunto.

Especificação Completa

Apresentação RabbitMQ

Série de vídeos Microsoft

Migrando de RabbitMQ para AmazonMQ