• Nenhum resultado encontrado

Substituição do AgentService pelo RabbitMQ

Um dos principais objetivos desta dissertação era a introdução de um middleware orientado a eventos responsável por toda a comunicação da plataforma. Assim, o primeiro passo do desenvol- vimento foi a substituição do middleware do AgentService pelo novo middleware, o RabbitMQ. A introdução do RabbitMQ implicou a identificação de todos os módulos da plataforma que uti- lizavam comunicação, tendo sido identificados cinco: Painel de Controlo, agentes ATC, agentes Veículo, Disturbances Manager e Ferramenta de Monitorização. As alterações realizadas foram aproximadamente similares em cada um dos módulos/aplicações.

O uso do RabbitMQ na plataforma implica a instalação do broker/servidor, neste caso foi usada a versão 3.8.2, numa máquina disponível para o efeito. A plataforma apenas precisa do endereço IP dessa máquina para que os agentes se consigam ligar. Neste primeiro passo do desenvolvimento foram mantidas todas as configurações padrão do broker do RabbitMQ. Para além disso, com o novo componente da arquitetura, o broker do RabbitMQ, é agora necessário que aquando do arranque do Painel de Controlo (com o objetivo de iniciar um simulação), sejam iniciados ambos o AgentService e o servidor do RabbitMQ.

5.1.1 Cenários de Comunicação da Plataforma do LIACC

A introdução do RabbitMQ não foi realizada de forma direta, isto é, apenas substituindo todas as chamadas ao middleware do AgentService por chamadas ao RabbitMQ. Como o RabbitMQ aumenta as possibilidades da comunicação, nomeadamente com a introdução da capacidade de broadcast explicito, foram identificados cenários de comunicação que são uma mais valia para

a plataforma. Os cenários identificados foram implementados e integrados na plataforma, sendo descritos abaixo.

• O cenário individual usado nas comunicações um-para-um. Cada agente tem a sua própria fila de mensagens onde outros agentes podem publicar mensagens. A fila tem um nome no formato "Agent-<IdAgente>-MessageQueue"em que <IdAgente> corresponde ao iden- tificador do agente (AID) a que pertence a fila. Essa fila está associada a um exchange do tipo Direct (chamado "DirectExchange"). Assim, as mensagens com routing key igual ao identificador do agente são enviadas para a fila de mensagens do agente. Um agente emissor só precisa de saber o identificador do agente para quem pretende enviar a mensagem, que pode ser encontrado com o uso das páginas amarelas e páginas brancas.

• O cenário de equipa usado nas comunicações broadcast para todos os elementos de uma equipa. Neste cenário são usados exchange do tipo Fanout com um exchange por equipa. Um exchange chama-se "FanoutExchange<IdEquipa>". Um agente apenas precisa de enviar uma mensagem para o exchange correto usando o identificador da equipa para a qual quer enviar a mensagem. No nosso caso, como queremos que cada elemento da equipa receba a mensagem, é necessário que cada agente da equipa tenha uma fila de mensagens ligada ao exchange da sua equipa. O nome da fila segue o formato "Agent-<IdAgente>-Team- <IdEquipa>-MessageQueue". O comportamento do RabbitMQ apenas usando uma fila seria distribuir uniformemente as mensagens por todos os agentes/consumidores.

Na solução anterior, com o AgentService, o envio de uma mensagem para os agentes de uma equipa implicava a procura nas páginas amarelas/brancas por todos os agentes que pertenciam a essa equipa (usando o identificador da equipa) e depois o envio da mensagem individualmente para cada um deles.

• O cenário de tipo de veículo usado nas comunicações broadcast para todos os veículos de um determinado tipo (por exemplo para todos os aviões). Neste cenário são usados exchange do tipo Fanout com um exchange por tipo de veículo no formato "FanoutEx- change<TipoVeículo>". Um agente apenas precisa de enviar uma mensagem para o ex- changecorreto usando o identificador do tipo de veículo para o qual quer enviar a mensa- gem. Cada agente veículo de um determinado tipo tem uma fila de mensagens no formato "Agent-<IdAgente>-<TipoVeículo>-MessageQueue".

Na solução anterior, com o AgentService, o envio de uma mensagem para os agentes de um determinado tipo de veículo não era possível.

• O cenário de tópico usado nas comunicações broadcast para todos os agentes interessa- dos num determinado tópico. Este cenário, mais genérico, é semelhante a um cenário de multicast em que agentes criam tópicos em que outros podem estar interessados. Neste cenário são usados exchange do tipo Fanout com um exchange por tópico no formato "Fa- noutExchange<Tópico>". Um agente que pretenda publicar num determinado tópico ape- nas precisa de enviar uma mensagem para o exchange correto usando o identificador do

5.1 Substituição do AgentService pelo RabbitMQ 65

tópico. Um agente subscritor tem uma fila de mensagens no formato "Agent-<IdAgente>- <Topico>-MessageQueue"onde recebe mensagens publicadas no tópico.

Na solução anterior, com o AgentService, esta solução genérica não era possível.

Estes cenários podem ser divididos num cenário de comunicação individual e três cenários de broadcast. O uso destes cenários está adaptado à plataforma do LIACC, mas o cenário de comunicação individual e de tópico broadcast poderiam ser aplicados em qualquer MAS cobrindo os cenários típicos destes sistemas [Paletta, 2012].

5.1.2 Serialização de Mensagens

O RabbitMQ envia mensagens em formato binário. Para o envio de mensagens com forma- tos mais complexos, normalmente modeladas por objetos, é necessário o uso de serialização. O processo de serialização consiste na transformação de um objeto numa representação em memória (bytes), que pode ser usada para mais tarde o reconstruir [Wenzel et al., 2020]. Esta representação em memória pode ter formato XML, JSON ou binário em função da ferramenta usada.

O desempenho do RabbitMQ é influenciado pelo tamanho das mensagens a enviar, influenci- ando também o desempenho da plataforma. Para além deste atraso causado por mensagens com tamanhos superiores, podemos também considerar o atraso introduzido pelo próprio processo de serialização. Os tempos de serialização influenciam a latência entre a necessidade do envio de uma mensagem, por um determinado agente, e a sua chegada ao agente destinatário. Assim surge a necessidade de encontrar e usar uma ferramenta de serialização que seja eficiente em termos de tempo e espaço.

A serialização para XML e JSON foi a primeira a surgir devido à facilidade com que é inter- pretada por humanos (ajuda na procura de problemas na comunicação) e ao seu uso em aplicações Web. O XML tende a ocupar mais espaço que o JSON, mas ambos ocupam normalmente mais espaço do que a serialização binária. Para além disso, a necessidade de serem interpretados ca- rácter a carácter torna também o processo mais lento [Mesfin et al., 2018]. Assim, para obter melhor desempenho na plataforma e porque não existe a necessidade das mensagens conseguirem ser interpretadas, optamos por ferramentas de serialização binária. A literatura referencia várias ferramentas como o Google’s Protocol Buffers (ProtoBuf1), o Apache Thrift2, o Apache Avro3e o MessagePack4[Giaimo et al., 2015,Eddelbuettel et al., 2016,Zhao et al., 2016].

De forma a perceber qual a que apresenta melhor desempenho, em termos de espaço e tempo para o uso na plataforma, decidimos realizar alguns testes de desempenho. Os testes consistem na serialização de um objeto que representa uma mensagem trocada entre agentes na plataforma. Foram realizados para as ferramentas mais referenciadas pela literatura e para a ferramenta de serialização binária padrão do C#. A Tabela5.1apresenta os resultados obtidos.

1Mais informação disponível emhttps://developers.google.com/protocol-buffers 2Mais informação disponível emhttp://thrift.apache.org/

3Mais informação disponível emhttps://avro.apache.org/ 4Mais informação disponível emhttps://msgpack.org/

Tabela 5.1: Comparação do Desempenho das Ferramentas de Serialização

.Net Bin.Formatter MessagePack ProtoBuf Apache Avro Apache Thrift

Serialização (ms) 0.25 0 0 0 3

Desserialização (ms) 0.25 0 0 0 0

Tamanho (Bytes) 4435 347 228 268 441

Os resultados mostram que todas as ferramentas apresentam bons tempos de serialização e desserialização, com exceção para o Apache Thrift que apresenta um tempo de serialização bas- tante superior. Por outro lado em termos de espaço notam-se maiores oscilações. O resultado da serialização com a ferramenta do .Net apresenta um tamanho mais de 10 vezes superior à fer- ramenta que se segue (Apache Thrift). Concluímos que a ferramenta que se adequa melhor aos objetos usados para a troca de mensagens pela plataforma é o Protobuf, por ser a que apresenta melhores resultados em termos de espaço. Assim, foi essa a ferramenta utilizada.