AMQP - Protocolo de Comunicação para IoT

Este post faz parte da série AMQP. Leia também os outros posts da série:

Introdução ao AMQP

 

Neste primeiro artigo iremos apresentar um protocolo de comunicação para dispositivos IoT - o AMQP (Advanced Message Queuing Protocol). A própria concepção de dispositivos IoT se funde à comunicação: não faria sentido falarmos de IoT sem pensarmos em como estes dispositivos se comunicam - seja entre eles, com o usuário ou, ainda, com um servidor remoto.

 

Ainda assim, falar somente em “comunicação” é bastante abrangente, uma vez que a comunicação pode ocorrer por meios distintos (óptica? com fio? sem fio?), de formas diferentes (síncrona? assíncrona?) e padronizadas por diferentes protocolos. Considerando o modelo OSI, que abstrai as redes de comunicação em 7 camadas, ao falarmos de AMQP, estamos falando da camada de aplicação. Assim, o AMQP pode ser entendido como um protocolo pertencente à mesma camada do MQTT ou, ainda, do HTTP.

 

O AMQP é um protocolo que “roda acima” do protocolo TCP, que pertence à camada de transporte. Tal como o MQTT, o AMQP é um protocolo que permite o envio e recebimento de mensagens de forma assíncrona - ou seja, quando enviamos uma mensagem não esperamos uma resposta imediata - independente do hardware, sistema operacional e linguagem de programação. De forma bastante genérica (e com ressalvas: vide referências), o AMQP pode ser enxergado como o equivalente assíncrono do HTTP, onde um cliente é capaz de comunicar-se com um broker “no meio do caminho”.

 

Antes de, propriamente, falarmos sobre o AMQP, cabe mencionarmos ótimas referências já publicadas aqui no Embarcados sobre a temática da comunicação em dispositivos IoT, como o infográfico do Felipe Lavratti, bem como o artigo do Marcelo Barros, que trata sobre MQTT. Mais adiante faremos um paralelo do MQTT em relação ao AMQP.

 

 

(Muito) Breve Histórico

 

O AMQP é um protocolo originalmente desenvolvido pela comunidade atuante no mercado financeiro, baseado no cliente (customer-driven) que visa permitir a interoperabilidade entre dispositivos. Atualmente, a versão do protocolo padronizada pela ISO/IEC 19464 é a 1.0. No entanto, este artigo baseia-se na utilização do RabbitMQ como broker de AMQP e, nativamente, este broker utiliza o AMQP 0-9-1 (embora também ofereça suporte ao AMQP 1.0). Desta forma, iremos focar no AMQP 0-9-1, que é bastante utilizado no RabbitMQ e em outros brokers.

 

 

Conceitos Iniciais

 

O broker é uma entidade que recebe mensagens de publishers - ou seja, clientes que produzem mensagens - e encaminha mensagens a consumers, que são clientes que recebem (consomem) mensagens. Assim, o AMQP é um protocolo bi-direcional onde um cliente pode enviar e receber mensagens de outros clientes através do broker.

 

Ao publicar uma mensagem, o cliente publisher encaminha esta mensagem a outra entidade denominada exchange, que de acordo com regras específicas (e programáveis!) denominadas bindings as encaminham para filas (queues) que, por sua vez, podem estar sendo consumidas por um outro cliente, o consumer. Broker, publishers, consumers, exchanges, bindings e queues são as palavras chaves para entender o funcionamento do protocolo e, tal como dito por um colega (Renan Biazotto), “o AMQP é um grande canivete suíço: ele oferece uma grande variedade de regras que podem ser altamente personalizadas de acordo com a finalidade de nossa aplicação.”

 

De forma simples e resumida, o funcionamento do AMQP pode ser comparado a um sistema de correios conforme mostra a Figura 1 a seguir: o cliente Publisher escreve uma mensagem e a encaminha para um exchange, que se assemelha a uma caixa de correio. A seguir, já no broker - que pode ser entendido como os Correios, por exemplo - esta mensagem é encaminhada de acordo com regras específicas (bindings) através de rotas a uma queue, que pode ser entendida como uma caixa postal, por exemplo. Finalmente, um cliente Consumer monitora a queue (caixa postal) para, então, ler a mensagem.

 

Diagrama do Funcionamento do Exchange tipo Direto no AMQP.
Figura 1- Diagrama do Funcionamento do Exchange tipo Direto no AMQP.

 

Uma das principais características do AMQP é que o publisher jamais publica uma mensagem diretamente em uma fila. A mensagem sempre é encaminhada ao exchange que, de acordo com seu tipo e com as configurações especificadas através de bindings, a encaminha para determinada fila ou a descarta.

 

Protocolo Programável (e Exchanges!)

 

Rotas, exchanges, filas e outras entidades podem ser programadas diretamente pelas aplicações (clientes). A função de administração do sistema passa a ser somente no sentido de criar regras de acesso e permissões para determinadas ações. Dessa forma, o AMQP 0-9-1 é um protocolo “programável”, deixando boa parte das ações a cargo dos usuários/clientes.

 

Esse grande “canivete suíço” que é o AMQP 0-9-1 proporciona aos desenvolvedores grande liberdade ao desenvolver aplicações específicas e personalizáveis. No entanto, o esforço concentra-se em compreender as especificidades do protocolo, bem como a correta utilização de suas entidades.

 

Falaremos agora de uma dessas entidades, os Exchanges!

 

Por que é importante conhecer os Exchanges e seus tipos?

 

O exchange é uma entidade que recebe as mensagens que chegam ao broker vindas de aplicações clientes. Estas aplicações desconhecem a existência das filas. É através do Exchange que determinada mensagem é roteada para uma ou mais filas a partir de regras denominadas bindings. Há alguns tipos de Exchanges que implementam diferentes características de roteamento das mensagens recebidas. A saber, são tipos de Exchanges: Direct, Fanout, Topic e Headers. Além do tipo, outros parâmetros definem um Exchange: nome, durabilidade, auto-delete, argumentos, etc.

 

As mensagens que são publicadas no broker e as mensagens que são consumidas possuem um parâmetro chamado routing key, que no caso de filas que são atreladas a um exchange, também pode ser chamado de binding key. Este parâmetro nada mais é do que um identificador do caminho da mensagem e serve de base para armazenar corretamente as mensagens em filas. Este conceito ficará mais claro a seguir, quando apresentarmos o Exchange do tipo Direto (Direct) e do tipo Tópico (Topic).

 

Direct Exchange

 

O Exchange do tipo Direto entrega mensagens às filas de acordo com o routing key da mensagem. Isto é, se uma fila foi bounded (roteada) a um exchange com determinado routing key (binding key), toda mensagem que chegar ao broker destinada a um exchange do tipo Direct com determinado routing key, será redirecionada à fila associada a este mesmo routing key (binding key). Este tipo de exchange é utilizado principalmente para a distribuição de tarefas entre diversos consumidores.

 

Diagrama do Funcionamento do Exchange tipo Direto.
Figura 2 - Diagrama do Funcionamento do Exchange tipo Direto.

 

Supondo-se o caso de uma tarefa complexa que deseja-se distribuir entre diversos consumidores (workers, neste caso), a Figura 2 exibe o funcionamento do Exchange do tipo direto: a mensagem é enviada ao broker contendo uma operação a ser realizada em uma imagem e, de acordo com o routing key da mensagem, o exchange do tipo Direct encaminha a mensagem para as filas que estão atreladas (bounded) ao exchange com o mesmo routing key (também conhecido como binding key, no caso das filas).

 

Topic Exchange

 

O Exchange do tipo Tópico (Topic) é utilizado para comunicação no padrão publica/subscreve (publish/subscribe) e, assim, é utilizado para monitorar mensagens de acordo com padrões no routing key da mensagem, ou seja, o consumidor pode “escolher” que tipo de mensagem deseja receber e, simetricamente, quem publica a mensagem no Exchange indica um assunto/tópico - através do routing key - ao qual a mensagem se refere.

 

Como um exemplo de aplicação, suponha que gostaríamos de implementar um sistema de logs no qual os consumidores monitoram mensagens de log de diferentes origens/módulos (kernel do sistema, gerenciamento de usuários, rede) e de diferentes níveis (informação, alertas, erros). Cada mensagem gerada contém tanto a origem (kernel/users/network) como o nível do log (info/warning/error) representados como uma lista de dois elementos (poderiam ser mais!) separados por pontos (“.”) no routing key. Por exemplo, a mensagem que contém o routing key igual a “ker.info” representa uma mensagem de log gerada pelo kernel do sistema e representa um nível informacional.

 

Consumidores destas mensagens podem monitorar determinado routing key (ou binding key, uma vez que estão associadas a uma fila) e executar ações específicas. Por exemplo, o consumidor A, que é responsável pela saúde de todo o sistema, está interessado em monitorar todas as mensagens de log de erros, independente do módulo que gerou a mensagem. Outro consumidor (B, por exemplo) está interessado somente nas mensagens do módulo de gerenciamento de usuários (users) independente do nível (info/warning/error). Para tal roteamento das mensagens, o exchange do tipo Topic permite a utilização de caracteres especiais no binding key das filas associadas ao exchange. Por fim, o consumidor C está interessado em todas as mensagens de log. Assim:

  • “*” pode substituir uma palavra no binding key;
  • “#” pode substituir uma ou mais palavras no binding key.

 

Para o consumidor A, este poderia consumir da fila com binding key igual a “*.error”, enquanto que o consumidor B consome de “users.*” e o consumidor C de “*.*”. Observe que o consumidor C poderia consumir também de “#”, porém no primeiro caso (“*.*”) o consumidor C receberia mensagens publicadas com exatamente duas palavras no routing key, enquanto que no segundo caso (“#”) consumiria qualquer mensagem publicada no exchange, independente da quantidade de palavras no routing key. Vejamos alguns exemplos.

 

A Figura 3 a seguir exibe a representação do fluxo de uma mensagem de log do tipo “users.error”. Neste caso, os consumidores A, B e C - associados às filas com bindings para “*.error”, “users.*” e “*.*”, respectivamente - recebem a mensagem de log com routing key “users.error”, uma vez que os critérios para estes bindings são todos satisfeitos:

 

Diagrama do Roteamento de uma Mensagem de Log “users.error” em um Topic Exchange.
Figura 3 - Diagrama do Roteamento de uma Mensagem de Log “users.error” em um Topic Exchange.

 

A Figura 4 a seguir representa o roteamento para uma mensagem com routing key igual a “users.info”. Observe que, para este caso, o binding key da fila 1 não é satisfeito e, portanto, a mensagem não é entregue ao consumidor A:

 

Diagrama do Roteamento de uma Mensagem de Log “users.info” em um Topic Exchange.
Figura 4 - Diagrama do Roteamento de uma Mensagem de Log “users.info” em um Topic Exchange.

 

Finalmente, a Figura 5 a seguir exibe o roteamento para uma mensagem com routing key igual a “kern.warning”. Observe que somente o Consumidor C recebe a mensagem, uma vez que é o único consumidor da fila que possui um binding compatível com a mensagem.

 

Diagrama do Roteamento de uma Mensagem de Log “kern.warning” em um Topic Exchange.
Figura 5 - Diagrama do Roteamento de uma Mensagem de Log “kern.warning” em um Topic Exchange.

 

Com esta breve introdução, pudemos ver (bem por cima!) um pouco do funcionamento do AMQP 0-9-1. O roteamento das mensagens, a criação de filas atreladas a determinado exchange de acordo com regras (bindings), a definição do tipo do exchange e até mesmo a criação de um exchange podem ser realizados pelos clientes. Assim, confirmando o que já dissemos, o AMQP 0-9-1 é um protocolo que possibilita bastante personalização através do lado das aplicações.

 

Com isto, podemos seguir para a seção Mão na Massa! onde iremos de fato apresentar uma aplicação utilizando o AMQP, focando no Exchange do tipo Topic. Vamos implementar nosso sistema de log! Aguarde o próximo artigo...

 

 

Saiba mais

 

MQTT-SN: MQTT para rede de sensores

Conectando-se ao DeviceHub com NodeMCU e MQTT

Modelos de comunicação para IoT

Outros artigos da série

AMQP - Instalação do cliente e do broker RabbitMQ >>
Este post faz da série AMQP. Leia também os outros posts da série:
NEWSLETTER

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Obrigado! Sua inscrição foi um sucesso.

Ops, algo deu errado. Por favor tente novamente.

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Tiago Medicci Serrano
Apaixonado por tecnologia! Plaquinhas, embarcados, clouds, IoT, comunidades e ensino: tudo isso faz parte do meu dia-a-dia, do trabalho às horas de lazer. Atualmente desenvolvo soluções inteligentes para o setor elétrico, SmartGrid e IoT na Time Energy, em Campinas.

Deixe um comentário

avatar
 
  Notificações  
Notificar