RabbitMQ e AMQP
Quem programa em Java a algum tempo já deve ter cruzado com JMS (Java Message Service) e também deve ter percebido que trabalhar com JMS apesar do conceito ser fácil, não é uma das tarefas mais agradáveis e simples. Isso porque a API possui muitas exceções que devem ser tratadas e as configurações das filas e do sistema são específicas de cada broker.
Mas afinal, pra quê usar JMS então? A resposta é simples, para programar de maneira assíncrona, e portanto mais voltado a reação do que a ação, ou seja, deixar a aplicação orientada a eventos (EDA – Event Driven Architeture) e conseguir distribuir melhor a carga entre servidores aumentando escalabilidade.
Já que mensageria é uma ferramenta poderosa, e JMS não colabora muito com sua utilização, foi criado o AMQP – Advanced Message Queuing Protocol. Diferente de JMS que define uma API Java, AMQP define um protocolo, ou seja, uma descrição de como os dados das mensagens trafegam pelo broker. Com isso qualquer aplicação que entenda esse protocolo consegue se comunicar com o broker independente de sua implementação, facilitando sua configuração e até mesmo a interoperabilidade de brokers.
Atualmente o broker mais utilizado que é open source e suporta tal protocolo é o RabbitMQ. Por isso veremos algumas características do mesmo. Outro fato a favor do RabbitMQ, é que agora faz parte do Springsource e portanto possui um bom suporte do spring-framework.
Começando com o RabbitMQ
Como vimos, uma das maiores vantagens de trabalhar com AMQP, é que a configuração independe do broker que estamos usando, portanto nosso trabalho com o RabbitMQ se resume a instalação e execução do serviço, tarefas as quais são muito simples.
Eu já instalei o RabbitMQ em máquinas com windows e com Linux (CentOS), por isso vou compartilhar ambas as experiências.
No Windows: Comece baixando o bundle completo do RabbitMQ que inclui todas as dependências para que o server funcione: Site oficial do RabbitMQ. Em seguida descompacte o conteúdo em uma pasta do seu sistema e rode o instalador que está dentro da pasta. Pronto! Ao sair do instalador, o serviço estará pronto pra uso, mas ainda não estará executando. Para isso basta abrir o painel de serviços do windows e iniciá-lo.
No CentOS: Pra variar, instalar o RabbitMQ no CentOS é simples com digitar no terminal:
sudo yum install rabbitmq-server
E pronto! O server está instalado, e basta iniciá-lo com:
sudo /sbin/service rabbitmq-server start
Configurando o broker AMQP
Repare que não estou especificando que iremos configurar o RabbitMQ, isso porque as cofigurações servem para qualquer broker AMQP.
Um broker JMS trabalha com filas sendo compartimentos para mensagens. Portanto é necessário configurar tais filas no broker. Para escutar as mensagens que são postadas nas filas, podemos utilizar selectors para filtrar algum tipo específico de mensagem baseado no cabeçalho da mensagem. Ainda podemos escolher o tipo de fila, sendo um modo ponto-a-ponto e um modo publish/subscribe. No primeiro modo, apenas um consumidor de mensagens escuta a fila, sendo que este receberá todas as mensagens enviadas não necessariamente no momento em que são postadas. No segundo modo múltiplos consumidores escutam a fila, sendo que a mensagem é entregue para todos os consumidores que o selector satisfazer as condições.
Com o AMQP é um pouco diferente. A primeira diferença notável, é que as mensagens não são publicadas diretamente nas filas, mas sim em uma nova estrutura chamada de Exchange. Exchanges recebem as mensagens encaminham para as filas baseados em routing keys, que especificam as filas que as mensagens pertencem. Portanto precisamos criar as filas também em um broker AMQP, mas dessa vez associando-as aos exchanges através de Bindings que são definidos pelas routing keys.
Note na imagem que um exchange pode rotear mensagens para mais de uma fila, e uma fila pode receber mensagens de mais de um exchange.
Em AMQP também temos o conceito de ponto-a-ponto chamdo de direct, sendo que nesse caso temos um exchange publicando apenas para uma fila, e também temos o conceito de Topic ou publish/subscribe, onde um exchange pode mandar para mais de uma fila. Nesse segundo caso, se for definida uma routing key, então o exchange irá encaminhar a mensagem para a fila com o binding referente a routing key. Caso não tenha sido definido uma routing key, as mensagens serão distribuídas para as filas de maneira igualitaria baseada em Round Robin.
Em AMQP ainda existe um terceiro modo: Fanout. Nesse modo o exchange pode estar associado a várias filas como em um topic, porém quando uma mensagem for postada no exchange, este replicará a mensagem em todas as filas que estiverem associadas a ele, sem levar em conta a routing key.
Bindings
Bindings entre exchanges e filas podem ser definidos apenas para explicitar uma ligação entre os dois, ou explicitando uma ligação condicional.
A condição para que o binding seja válido é definido pela routing key e pode ser definido de algumas maneiras:
- uma string fixa;
- uma string usada como padrão para fazer o match com as routing keys;
- múltiplas strings definindo mais de uma routing key;
- múltiplos strings usadas como padrão para match;
- comparação algorítmica baseada em uma SQL executada sobre o cabeçalho da mensagem;
- inspeção de conteúdo, verificando se o conteúdo da mensagem atende a uma determinada condição.
Spring AMQP
O RabbitMQ agora é um projeto da springsource, portanto existe já em desenvolvimento e inclusive com milestones publicados e disponíveis em um repositório do maven:
|
1
2 3 4 5 |
? ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? > |
Todo o projeto está desenvolvido com o ideal do spring e portanto os conceitos básicos e já conhecidos como injeção de dependência e facilidade de configuração e uso estão muito bem empregados no projeto.
Seguindo essa linha existe um classe que serve de template para um broker AMQP.
Veremos no screencast a seguir como adotar utilizar o Spring-AMQP em seu projeto e algumas facilidades e dificuldades.
Por @Gust4v0_H4xx0r




