middleware com escalonamento de aplicaÇÕespericas/orientacoes/escalonament... · soluções para...

66
UNIVERSIDADE REGIONAL DE BLUMENAU CENTRO DE CIÊNCIAS EXATAS E NATURAIS CURSO DE CIÊNCIA DA COMPUTAÇÃO BACHARELADO MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕES PAULO MATHEUS BAEHR WEBER BLUMENAU 2016

Upload: others

Post on 23-Jul-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

UNIVERSIDADE REGIONAL DE BLUMENAU

CENTRO DE CIÊNCIAS EXATAS E NATURAIS

CURSO DE CIÊNCIA DA COMPUTAÇÃO – BACHARELADO

MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕES

PAULO MATHEUS BAEHR WEBER

BLUMENAU

2016

Page 2: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

PAULO MATHEUS BAEHR WEBER

MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕES

Trabalho de Conclusão de Curso apresentado

ao curso de graduação em Ciência da

Computação do Centro de Ciências Exatas e

Naturais da Universidade Regional de

Blumenau como requisito parcial para a

obtenção do grau de Bacharel em Ciência da

Computação.

Prof. Francisco Adell Péricas - Orientador

BLUMENAU

2016

Page 3: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕES

Por

PAULO MATHEUS BAEHR WEBER

Trabalho de Conclusão de Curso aprovado

para obtenção dos créditos na disciplina de

Trabalho de Conclusão de Curso II pela banca

examinadora formada por:

Presidente: Prof. Francisco Adell Péricas, Ms. – Orientador, FURB

______________________________________________________

Membro: Prof. Mauro Marcelo Mattos, Dr. – FURB

______________________________________________________

Membro: Prof. Miguel Alexandre Wisintainer, Ms. – FURB

Blumenau, 05 de Julho de 2016

Page 4: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

Dedico este trabalho a minha mãe, que sempre

me incentivou a estudar e me apoiou durante o

período da faculdade.

Page 5: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

AGRADECIMENTOS

À minha família pelo incentivo ao estudo e pelos cafés durante noites de trabalho.

Aos meus amigos pelas dicas e dúvidas esclarecidas.

Ao meu orientador pela motivação e apoio no cumprimento dos prazos.

Aos professores e colegas de curso, que contribuíram para o meu aprendizado durante

o curso.

Page 6: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

Não é preciso ter olhos abertos para ver o sol,

nem é preciso ter ouvidos afiados para ouvir o

trovão. Para ser vitorioso você precisa ver o

que não está visível.

Sun Tzu

Page 7: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

RESUMO

Este trabalho descreve o desenvolvimento de um middleware utilizando a ferramenta

RabbitMQ para envio e recebimento de requisições, permitindo integração com outras

linguagens de programação também suportadas pela ferramenta. O middleware inicializa e

encerra aplicações de acordo com a demanda de requisições. Para inicializar ou encerrar

aplicações é necessário que esteja em execução na máquina em questão um aplicativo de

extensão ao middleware responsável pela inicialização de aplicativos. Para validar este

trabalho será utilizado um aplicativo que simula a geração do XML de uma nota fiscal de

produto, e outro aplicativo que processa o XML gerado, retornando um resultado. O

middleware armazena o tempo de execução de cada requisição para prever o tempo estimado

de outras requisições do mesmo tipo e priorizar algumas requisições que levam menos tempo.

Os resultados obtidos a partir dos experimentos e testes realizados demonstram que o

middleware é capaz de iniciar e encerrar aplicações de acordo com a demanda e priorizar

requisições considerando o tempo estimado de execução, sem que as requisições mais

demoradas fiquem sempre no final da fila.

Palavras-chave: Middleware. RabbitMQ. C#. Escalonamento.

Page 8: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

ABSTRACT

This word describes the development of a middleware using RabbitMQ tool for sending and

receiving requests, allowing integration with other programming languages also supported by

the tool. The middleware initializes and closes applications according to demand requests. To

boot or shut down applications you must be running on the machine in question an extension

application middleware responsible for application startup. To validate this work will be used

an application that simulates the generation of XML of an invoice product, and other

application that processes the XML generated by returning a result. The middleware stores the

run time of each request to predict the estimated time of other requests of the same type and

prioritize some requests that take less time. The results from the experiments and tests show

that the middleware is able to start and stop applications according to demand and prioritize

requests considering the estimated runtime, without the most time-consuming requests always

stay at the end of the queue.

Key-words: Middleware. RabbitMQ. C#. Schedulling.

Page 9: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

LISTA DE FIGURAS

Figura 1– Ilustração de um sistema distribuído ........................................................................ 14

Figura 2 – Integração múltipla ponto a ponto .......................................................................... 16

Figura 3– Integração com message broker ............................................................................... 16

Figura 4 – Rede integrada com múltiplos message brokers ..................................................... 17

Figura 5 – Camada Middleware ............................................................................................... 18

Figura 6 – RPC ......................................................................................................................... 19

Figura 7 – Comunicação com Middleware Orientado a Mensagens ........................................ 20

Figura 8 – Troca de mensagens através de filas ....................................................................... 21

Figura 9 – Publicação e inscrição ............................................................................................. 22

Figura 10 – Configuração de alerta .......................................................................................... 27

Figura 11 – Política de incremento de quantidade de instâncias .............................................. 28

Figura 12 – Comparação entre o consumo real e o previsto .................................................... 29

Figura 13 - Carga prevista e carga escalonada pelo AAS ........................................................ 29

Figura 14 – Agentes do sistema e principais interações ........................................................... 31

Figura 15 – Diagrama de atividades da aplicação servidora .................................................... 32

Figura 16 - Diagrama de atividades da aplicação AppStarter .................................................. 33

Figura 17 – Diagrama de atividades da aplicação Monitor ...................................................... 34

Figura 18 – Diagrama de atividades do Middleware: Envio de dados estatísticos .................. 34

Figura 19 – Recebimento de dados estatísticos ........................................................................ 35

Figura 20 – Recebimento de novas requisições ....................................................................... 35

Figura 21 – Registro de AppStarter .......................................................................................... 36

Figura 22 – Registro de Monitores ........................................................................................... 36

Figura 23 – Tratamento de requisições..................................................................................... 37

Figura 24 – Verificação da quantidade de aplicações servidoras ............................................. 37

Figura 25 – Modelo entidade relacional ................................................................................... 38

Figura 26 – Primeira parte dos gráficos de informações de uso do primeiro teste ................... 55

Figura 27 – Segunda parte dos gráficos de informações de uso do primeiro teste ................... 56

Figura 28 – Fila de mensagens no broker e taxa de mensagens do primeiro teste ................... 57

Figura 29 - Primeira parte dos gráficos de informações de uso do segundo teste .................... 59

Figura 30 – Segunda parte dos gráficos de informações de uso do segundo teste ................... 60

Figura 31 – Fila de mensagens do broker e taxa de mensagens do segundo teste ................... 61

Page 10: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

LISTA DE QUADROS

Quadro 1 – Envio de mensagens .............................................................................................. 40

Quadro 2 – Recepção de mensagens ........................................................................................ 41

Quadro 3 – Preenchimento de campos para publicação da mensagem na aplicação cliente.... 42

Quadro 4 – Criação e Serialização de Nota em formato XML. ............................................... 43

Quadro 5 – Criação do consumidor utilizado na leitura de respostas ...................................... 43

Quadro 6 – Utilização do consumidor de mensagens............................................................... 44

Quadro 7 – Tratamento da requisição pela aplicação servidora ............................................... 45

Quadro 8 – Inicialização de aplicação servidora ...................................................................... 46

Quadro 9 – Inicialização de contadores de performance .......................................................... 47

Quadro 10 – Cálculo dos contadores de performance .............................................................. 48

Quadro 11 – Verificação das aplicações ainda em execução ................................................... 48

Quadro 12 – Criação dos gráficos com JFreeChart .................................................................. 49

Quadro 13 – Criação de séries .................................................................................................. 49

Quadro 14 – Adição de pontos em gráfico utilizando JFreeChart ........................................... 49

Quadro 15 - Adição de mensagens na fila ................................................................................ 50

Quadro 16 – Verificação se a máquina pode executar requisição ............................................ 51

Quadro 17 – Envio de requisição e cálculo de tempo de execução .......................................... 52

Quadro 18 – Verificação de quantidade de aplicações servidoras ativas ................................. 53

Quadro 19 – Verificação de AppStarter apto a iniciar aplicação ............................................. 54

Page 11: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

SUMÁRIO

1 INTRODUÇÃO .................................................................................................................. 12

1.1 OBJETIVOS ...................................................................................................................... 13

1.2 ESTRUTURA.................................................................................................................... 13

2 FUNDAMENTAÇÃO TEÓRICA .................................................................................... 14

2.1 SISTEMAS DISTRIBUIDOS ........................................................................................... 14

2.2 MESSAGE BROKER ....................................................................................................... 16

2.3 MIDDLEWARE ................................................................................................................ 17

2.3.1 Remote Procedure Call (RPC) ........................................................................................ 19

2.3.2 Object Oriented Middleware (OOM).............................................................................. 20

2.3.3 Message Oriented Middleware (MOM).......................................................................... 20

2.3.3.1 Modelo de envio de mensagens .................................................................................... 21

2.4 ESCALONAMENTO DE PROCESSOS .......................................................................... 23

2.4.1 Fairness ........................................................................................................................... 24

2.4.2 Genetic Algorithm Scheduling ........................................................................................ 24

2.4.3 Throughput ...................................................................................................................... 25

2.4.4 Turnaround ...................................................................................................................... 25

2.4.5 Shortest Job First ............................................................................................................. 26

2.5 RABBITMQ ...................................................................................................................... 26

2.6 TRABALHOS CORRELATOS ........................................................................................ 26

2.6.1 AAS ................................................................................................................................. 26

2.6.2 Scryer .............................................................................................................................. 28

3 DESENVOLVIMENTO .................................................................................................... 30

3.1 REQUISITOS .................................................................................................................... 30

3.2 ESPECIFICAÇÃO ............................................................................................................ 30

3.2.1 Diagrama de Arquitetura ................................................................................................. 30

3.2.2 Diagramas de atividades. ................................................................................................ 31

3.2.3 Modelo Entidade Relacionamento .................................................................................. 38

3.3 IMPLEMENTAÇÃO ........................................................................................................ 38

3.3.1 Técnicas e ferramentas utilizadas.................................................................................... 39

3.3.1.1 Aplicação cliente .......................................................................................................... 41

3.3.1.2 Aplicação servidora ...................................................................................................... 44

Page 12: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

3.3.1.3 AppStarter ..................................................................................................................... 45

3.3.1.4 Aplicação de monitoramento ........................................................................................ 49

3.3.1.5 Middleware ................................................................................................................... 50

3.4 RESULTADOS E DISCUSSÕES ..................................................................................... 54

3.4.1 Execução em uma máquina ............................................................................................. 54

3.4.2 Execução em duas máquinas ........................................................................................... 58

3.4.3 Principais dificuldades ao utilizar o RabbitMQ .............................................................. 62

CONCLUSÕES ....................................................................................................................... 63

3.5 EXTENSÕES .................................................................................................................... 63

REFERÊNCIAS ..................................................................................................................... 64

Page 13: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

12

1 INTRODUÇÃO

Segundo Sordi (2007, p. 1), “existe uma crescente demanda das organizações por

soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas

encontram dificuldades nesta integração, essencialmente os problemas que envolvem a

integração de sistemas legado com sistemas em desenvolvimento, ou na integração entre

vários sistemas interconectados pela rede, onde cada sistema desenvolve um papel específico,

como se conectar com o mundo real ou se conectar com outros dispositivos através da internet

(KRAKOWIAK, 2009, p. 16).

Segundo Machado (2014, p. 37), “O middleware é uma camada de software adicional

que fica entre a comunicação de rede oferecida pelo sistema operacional e a camada de

aplicação”. Atualmente existem diversas aplicações que já fazem o papel de middleware para

a integração de sistemas, desde modelos mais simples até modelos mais robustos.

Neste trabalho pretende-se apresentar uma solução capaz de integrar sistemas em

diversas plataformas e linguagens e escalonar aplicações (alocar aplicações de acordo com a

demanda). Será implementada uma política de escalonamento que é composta por elementos

de mais de uma política de escalonamento, desta forma, considerando fatores como a

quantidade de requisições por segundo, e ordenando as requisições através de uma fila, onde o

primeiro a entrar é o primeiro a sair, porém, requisições cujo tempo estimado de execução é

baixo podem ser priorizadas.

Para aplicar e validar o middleware, foi implementada uma aplicação simplificada de

Emissão de Notas Fiscais Eletrônicas (NF-e), onde questões como layouts serão abstraídos,

além disto a NF-e não será enviada para a Secretaria de Estado da Fazenda (SEFAZ), mas

será enviada para um serviço local que irá emular a SEFAZ, de modo que todo o ambiente

seja controlado.

O middleware proposto neste trabalho foi desenvolvido em C#, utilizando a plataforma

Visual Studio, e foi executado em uma máquina com Windows. A plataforma e linguagem

foram escolhidas devido a facilidade de se utilizar o Visual Studio.

Uma das características exploradas no trabalho é o fato de o middleware poder se

comunicar com aplicações desenvolvidas em mais de uma linguagem. Isto se deve à

utilização da ferramenta RabbitMQ, cuja responsabilidade é abstrair a utilização do socket nas

várias linguagens de programação suportadas, propiciando maior facilidade em

implementações multilinguagem.

Page 14: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

13

Neste trabalho foi desenvolvida também uma aplicação de monitoramento do

middleware e das máquinas que iniciam aplicações, de modo a facilitar a detecção de

possíveis oportunidades de melhoria. A implementação da aplicação foi no Eclipse com o

plug-in WindowBuilder. Foi utilizada a biblioteca JFreeChart para a criação dos gráficos

necessários.

1.1 OBJETIVOS

O objetivo deste trabalho é desenvolver um middleware utilizando a biblioteca

RabbitMQ, capaz de permitir a integração de sistemas multiplataforma e multilinguagem.

Os objetivos específicos do trabalho são:

a) desenvolver uma aplicação de envio de NF-e para validação do middleware;

b) desenvolver o middleware implementando escalonamento de aplicações;

c) exibir relatórios de status de utilização do middleware e das máquinas que iniciam

aplicações.

1.2 ESTRUTURA

Este trabalho está dividido em quatro capítulos. O primeiro capítulo é composto pela

justificativa do trabalho, os objetivos e a apresentação de sua estrutura.

O segundo capítulo apresenta a fundamentação teórica, abordando conceitos sobre

sistemas distribuídos, message broker, middleware, escalonamento de processos, nota fiscal

eletrônica e RabbitMQ, esclarecendo conceitos utilizados no desenvolvimento do trabalho.

No terceiro capítulo é apresentado o desenvolvimento do aplicativo, iniciando pelos

requisitos e a especificação por meio de diagramas. A seguir é detalhada a implementação do

aplicativo, descrevendo técnicas e ferramentas utilizadas, após isto, são apresentados os

resultados obtidos.

Por fim, o quarto capítulo apresenta as conclusões e as sugestões para extensões e

melhorias futuras.

Page 15: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

14

2 FUNDAMENTAÇÃO TEÓRICA

Neste capítulo são explorados os principais assuntos necessários para a realização do

trabalho. Estes estão subdivididos em cinco partes, sendo que na seção 2.1 são conceituados

Sistemas Distribuídos, na seção 2.2 é apresentado o conceito de message broker. A seção 2.3

trata de conceituar um middleware e a seção 2.4 aborda formas de escalonamento de serviços.

Já na seção 2.5 é apresentada a ferramenta RabbitMQ e na seção 2.6 são apresentados

trabalhos correlatos a este.

2.1 SISTEMAS DISTRIBUIDOS

Segundo Blair et al. (2013), um sistema distribuído é composto por componentes

localizados na rede de computadores que se comunicam e coordenam as atividades através de

mensagens. A principal motivação para construir e usar sistemas distribuídos é proveniente do

desejo de compartilhar recursos, sendo o termo “recurso” bastante abstrato. Pode-se

considerar recurso como o conjunto de coisas que podem ser compartilhadas de maneira útil

em um sistema de computadores interligados em rede. Ele abrange desde componentes de

hardware, como discos, impressoras ou processamento, até entidades definidas pelo software,

como arquivos, bancos de dados e objetos de dados de todos os tipos.

A Figura 1 ilustra a arquitetura de um sistema distribuído, onde vários sistemas se

comunicam através de uma rede local, que possui uma entrada para a internet.

Figura 1– Ilustração de um sistema distribuído

Fonte: Thiruvathukal e Kaylor (2013).

Um sistema distribuído possui alguns desafios, como a necessidade de tratamento de

concorrência, pois vários dispositivos podem solicitar o mesmo recurso e é necessário que

algum intermediário gerencie o acesso aos recursos. Caso esse gerenciamento não seja efetivo

Page 16: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

15

podem ocorrer situações de deadlock, que são situações onde um processo para continuar

precisa de um determinado recurso que está mantido por outro processo, da mesma forma o

outro processo para continuar precisa de algum recurso já sendo utilizado, e por tanto nenhum

dos processos consegue continuar.

Outro desafio de um sistema distribuído é a necessidade de gerenciamento de tempo,

visto que diferentes dispositivos podem estar em diferentes locais, com diferentes horários e a

comunicação entre os dispositivos pode levar tempos diferente, devido a própria conexão de

rede.

A escalabilidade também é um desafio dos sistemas distribuídos. Um sistema é descrito

como escalável se permanece eficiente quando há um aumento significativo no número de

recursos e no número de usuários (BLAIR et al., 2013). Esta necessidade por escalabilidade se

aplica quando, por exemplo, em diferentes horários do dia, um sistema tem um aumento

muito grande na quantidade de acessos simultâneos.

Porém, deve-se considerar que em períodos de pouca utilização do sistema o mesmo

pode “diminuir de tamanho” para economizar energia. Desta forma um sistema distribuído

pode identificar a necessidade de aumentar ou diminuir os recursos conforme a demanda.

Conforme BLAIR et al. (2013) , o tratamento de falhas é um desafio para um sistema

distribuído, pois a falha de um dispositivo não deveria inviabilizar as operações. Para isso um

sistema deve estar apto a redirecionar a demanda para outro dispositivo que esteja apto a tratar

a demanda. Em ambientes onde existe um middleware este tratamento pode ser mais

complexo, pois nem sempre em caso de falha de um middleware é possível que outro assuma

o seu lugar e continue as tarefas pendentes. Existe o conceito de redundância, que consiste em

manter sempre um backup das informações disponíveis, seja um disco com os arquivos, um

servidor a mais para ser acionado, um middleware que está sincronizado com o atuante, etc.

Segundo BLAIR et al. (2013), um desafio de um sistema distribuído é facilitar o

compartilhamento de novos recursos, levando em consideração a quantidade de hardware e

software novos que chegam ao mercado. É importante que o sistema esteja apto a aceitar

novos recursos sem necessidade de restruturação do sistema.

A segurança em um sistema distribuído é um desafio complexo. Segundo Blair et al.

(2013), a segurança é composta por três componentes: confidencialidade (proteção contra

acesso não autorizado), integridade (proteção contra alteração da informação) e

disponibilidade (proteção contra interferência nos meios de acesso aos recursos). Há ainda um

desafio para lidar com ataques de negação de serviço, que consiste em uma forma de ataque

onde um servidor recebe tantas requisições que acaba travando e ficando indisponível. Este

Page 17: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

16

tipo de ataque é em geral difícil de lidar, pois pode ser complexo definir quando uma

requisição é maliciosa ou não.

2.2 MESSAGE BROKER

Segundo Hohpe e Woolf (2003, p. 287), em sistemas distribuídos onde existe a troca

de mensagens entre as aplicações, as aplicações podem precisar trocar mensagens com

diversas outras aplicações, podendo criar uma sobrecarga de canais de comunicações entre

aplicações. Um exemplo de rede interconectada pode ser visto na Figura 2.

Figura 2 – Integração múltipla ponto a ponto

Fonte: Hohpe e Woolf (2003)

Para resolver este problema foi desenvolvido o message broker. Segundo Hohpe e

Woolf (2003, p. 288) pode-se definir um message broker como uma aplicação responsável

por receber mensagens de múltiplos remetentes, determinar o destino correto e enviar a

mensagem ao canal de comunicação com o destino correto. Na Figura 3 está ilustrada a

utilização de um message broker.

Figura 3– Integração com message broker

Fonte: Hohpe e Woolf (2003)

A vantagem de centralizar e diminuir a quantidade de canais de comunicação pode

também se tornar uma desvantagem, pois pode haver sobrecarga do message broker e o

mesmo acabar se tornando o gargalo do sistema. Para resolver esta situação é possível, por

Page 18: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

17

exemplo, criar vários message brokers e interligá-los de forma hierárquica. Na Figura 4 é

ilustrado um exemplo de uma rede de message brokers.

Figura 4 – Rede integrada com múltiplos message brokers

Fonte: Hohpe e Woolf (2003)

2.3 MIDDLEWARE

Segundo Machado (2014, p. 37), “O middleware é uma camada de software adicional

que fica entre a comunicação de rede oferecida pelo sistema operacional e a camada de

aplicação.”. Ele oferece, portanto, uma abstração sobre a camada de rede, necessitando que o

usuário conheça apenas a localização do middleware, e este encaminha a requisição até o

destino. A Figura 5 ilustra a camada do middleware em uma comunicação entre dois hosts.

Page 19: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

18

Figura 5 – Camada Middleware

Fonte: Bakken (2003).

Desenvolver para ambientes distribuídos utilizando um middleware tem benefícios,

como o fato de possibilitar que um programador desenvolva o lado servidor do sistema sem

muito conhecimento do lado cliente, embora ainda seja necessário conhecer o formato de

mensagem esperada pelo outro lado. Outra vantagem é o fato de ocultar boa parte da

complexidade do tratamento da comunicação via rede e da distribuição dos sistemas. Porém,

segundo Bernstein (1993, p. 5), surgem novas dificuldades como a necessidade de distinguir

quais funções ficam no lado cliente e quais ficam no lado servidor.

Segundo Bernstein (1993, p. 5), o grande número de middlewares disponíveis e o

grande número de serviços suportados acabam se tornando uma barreira em sua utilização,

pois é necessária muita programação para poder utilizá-los. Mesmo quando um middleware

possui poucos serviços, ao considerar todas as chamadas, necessidade de programação de

interfaces e definição dos dados acaba se tornando uma programação complexa.

Existem middlewares construídos para diferentes propósitos que disponibilizam

diferentes serviços. Segundo Varela (2007 p. 4), os middlewares comumente fornecem os

seguintes serviços:

a) serviços de comunicação: serviço para abstrair a complexidade da rede, a forma da

comunicação varia de acordo com a categoria do middleware;

b) serviços de acesso a base de dados: serviços que permitem execução de consultas

em um ou mais servidores, assegurando integridade dos dados disponibilizados

para a aplicação;

Page 20: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

19

c) serviços de planejamento de execução: serviços que permitem executar múltiplos

processos simultaneamente, balanceamento de carga, priorização de tarefas;

d) serviços de segurança: serviços comumente utilizados para conectar sistemas

distintos, onde cada um possui seu próprio sistema de segurança;

e) serviços de diretório: serviços para administrar recursos de rede.

Nas próximas seções serão exploradas algumas categorias de middleware.

2.3.1 Remote Procedure Call (RPC)

Consiste em um middleware onde o cliente solicita a execução de um método no

servidor. Para isto, o cliente converte os parâmetros em uma mensagem e envia ao servidor,

onde os parâmetros são novamente convertidos e a ação é executada e retornada ao cliente. As

vantagens deste tipo de middleware são a possibilidade de receber vários tipos de parâmetros,

retornar mesmo sem conexão de rede e suportar tratamento de exceção. Porém, as

desvantagens incluem a falta de escalabilidade devido ao fato de não possuir mecanismo de

replicação e por ser um processo rígido e acoplado ao processo (ROSENBAND, 2007).

A Figura 6 ilustra o fluxo durante uma invocação de um método através do RPC, onde

ilustra que os stubs (classes geradas automaticamente por um compilador) são responsáveis

pela interação com a rede, eliminando a necessidade de a aplicação se preocupar com a

complexidade da comunicação em rede.

Figura 6 – RPC

Fonte: Rosenband (1997).

Page 21: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

20

2.3.2 Object Oriented Middleware (OOM)

É uma categoria de middleware que possui um message broker, que tem por objetivo

traduzir a mensagem do formato enviado para o formato esperado pelo receptor, conhecido

como Object Request Broker (ORB). Segundo Maciel (2014, p. 8), ORB consiste em uma

evolução do RPC, onde a comunicação ocorre através de objetos.

2.3.3 Message Oriented Middleware (MOM)

Uma das principais vantagens deste tipo de middleware é o suporte a mensagens

assíncronas, possibilitando que a aplicação envie mensagens, continue o seu processamento e

apenas busque pela resposta mais tarde, ou em momentos de inatividade. A aplicação pode

aguardar a mensagem logo após seu envio, da mesma forma que seria feito caso o tratamento

fosse síncrono.

A Figura 7 ilustra a comunicação entre duas aplicações através de um middleware

orientado a mensagens, No exemplo ilustrado as aplicações possuem três camadas, a cama de

aplicação, a camada de interface de troca de mensagens, e a camada de troca de mensagens do

cliente, sendo este último responsável pela comunicação com o middleware.

Figura 7 – Comunicação com Middleware Orientado a Mensagens

Fonte: Monson-Haefel e Chappell (2000).

Para os middlewares orientados a mensagem, a comunicação ocorre por via de

mensagens que são postadas ou lidas de filas. A ordem das mensagens na fila é definida por

algum algoritmo em particular, sendo em geral utilizado o modelo First-in First-out (FIFO).

O cliente envia uma mensagem, que é adicionada na fila, e o middleware então consome as

mensagens, removendo-as da fila.

As filas podem ter algumas propriedades alteradas, como seu tamanho, nome,

algoritmo de ordenação, entre outros. Cada aplicação pode ter sua própria fila, assim como as

Page 22: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

21

filas podem ser compartilhadas entre aplicações. Tipicamente os MOMs suportam várias filas

com diferentes propósitos.

2.3.3.1 Modelo de envio de mensagens

Segundo Mahmoud (2004, p. 8), existem dois modelos comumente disponíveis, o

modelo ponto a ponto e o modelo de publicação e inscrição. Ambos os modelos são baseados

em trocas de mensagens através de uma fila.

O Modelo de fila de mensagens é um modelo ponto a ponto, onde o primeiro

consumidor consome uma mensagem de acordo com o algoritmo definido e a mensagem é

retirada da fila. Apenas um consumidor recebe a mensagem e apenas uma vez.

A Figura 8 ilustra um sistema de troca de mensagens onde existem duas filas e existem

produtores que adicionam mensagens na fila e consumidores que removem mensagens da fila.

Neste exemplo cada produtor/consumidor interage apenas com uma fila, porém, é possível

que um produtor produza para mais de uma fila, assim como um consumidor pode consumir

de mais de uma fila.

Figura 8 – Troca de mensagens através de filas

Fonte: Novell (2004?).

Segundo Blair et al. (2013), uma propriedade crucial de uma fila de mensagens é a

persistência, isto é, a fila de mensagem irá armazenar as mensagens até que as mesmas sejam

consumidas, ou que seja recebida uma mensagem de acknowledge, informando que a

mensagem já foi reconhecida e está sendo tratada e não precisa mais ser armazenada.

Segundo Blair et al. (2013), vários sistemas comerciais necessitam do uso de

mensagens transacionadas. Elas são utilizadas quando se pretende executar várias tarefas e as

alterações apenas serão confirmadas se todas as tarefas forem executadas corretamente. Em

Page 23: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

22

ambientes onde existem vários consumidores de mensagens este tratamento pode ser bastante

complexo devido à possibilidade de diferentes consumidores tratarem as tarefas.

Outro recurso disponível em sistemas comerciais como o WebSphere MQ é o suporte a

transmissão confidencial de mensagens utilizando SSL. Além disto, é possível utilizar um

controle de autenticação e acesso.

No modelo de publicação e inscrição, Segundo Eugster et al. (2003), aplicações

declaram interesse em um tipo de evento ou padrão de evento, e quando alguma mensagem é

publicada que se encaixa nos interesses registrados a aplicação é notificada. Uma forma de

implementar isto seria cada tipo de mensagem ter sua própria fila, onde cada consumidor

procura apenas em determinadas filas e cada produtor posta mensagens apenas em

determinadas filas, de acordo com o tipo da mensagem.

Na Figura 9 é apresentado um exemplo de sistema de troca de mensagens através do

sistema de publicação e inscrição, ilustrando produtores produzindo mensagens do mesmo

tópico e de tópicos diferentes, além de consumidores consumindo mensagens de diferentes

tópicos. Além disto, é ilustrado o fato de que as mensagens são replicadas conforme o número

de inscritos para o tópico. No caso do “Topic A”, como existem três consumidores inscritos, a

mensagem é replicada três vezes.

Figura 9 – Publicação e inscrição

Fonte: Novell (2004?).

Segundo Blair et al. (2013), este modelo de publicação e inscrição é utilizado, por

exemplo, para o tratamento de propagandas da Google, o Google Ads, onde os usuários são

Page 24: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

23

inscritos em determinados tópicos de acordo com o histórico de navegação. Quando um

anúncio é publicado todos que foram inscritos para aquele tópico visualizam a propaganda.

Existem diferentes formas de tratar o esquema de publicação e inscrição. Existe a

forma baseada em canais, onde uma aplicação se inscreve para receber todas as mensagens do

canal, e as mensagens são publicadas sempre em um canal e todos que se subscreveram no

canal a recebem. É de certa forma semelhante a comunicação ponto a ponto.

Existe o tratamento baseado em tópicos, onde uma aplicação se registra para um

determinado tópico em um broker, e as publicações informam qual o tópico em que serão

publicadas. Segundo Eugster et al.(2003) a melhoria mais útil foi a possibilidade de utilizar a

hierarquia para organizar os tópicos. A hierarquia permite, por exemplo, existir o tópico

“Carro” e o tópico “Automóvel”, onde ao se inscrever para o tópico “Automóvel”

automaticamente é inscrito no tópico “Carro”, pois o conjunto “Carro” pertence ao conjunto

“Automóvel”.

O tratamento baseado em conteúdo é uma abordagem que generaliza a abordagem via

tópicos, pois permite a flexibilização das inscrições através de queries. Uma aplicação pode se

inscrever para receber mensagens do tipo “Carro” ou “Caminhão” da Ford. A gramática das

queries varia de acordo com o sistema.

Segundo Eugster et al.(2003), existe o tratamento baseado no tipo, onde é possível

receber notificações de acordo com o tipo de interesse. É possível ainda filtrar o conteúdo de

acordo com o conteúdo do objeto, a partir das propriedades públicas.

2.4 ESCALONAMENTO DE PROCESSOS

O escalonamento consiste em uma técnica utilizada por processos para dividir sua

carga de tarefas entre os processadores das tarefas de modo a maximizar o indicador de

Qualidade de Serviço (QoS), sendo que essa qualidade é medida de acordo com parâmetros

que podem variar de acordo com o processo (ABIRAMI, RAMANATHAN; 2012, p. 12). Por

exemplo, uma emissão de nota fiscal do consumidor (NFC) deve garantir que seja o mais

próximo de instantâneo possível, pois um cliente de um supermercado não pretende ficar

vários minutos na fila aguardando a emissão da nota. Logo, percebe-se, que para este tipo de

serviço é importante garantir que nada fique na fila por muito tempo, caso contrário pode

deixar de gerar lucro para o supermercado.

Segundo Senger (2002), para efetuar as decisões com relação à divisão de carga de

tarefas, o escalonador se baseia em políticas de escalonamento, que representam decisões

como “permitir que aplicações com menor tempo de execução sejam executadas

Page 25: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

24

prioritariamente” ou “permitir que aplicações interativas tenham maior prioridade na

utilização de recursos”. A partir destas políticas e considerando o ambiente de execução, o

escalonador efetua a distribuição da carga.

Algumas das políticas necessitam de informações, como o tamanho da fila, utilização

de CPU, memória, entre outras informações. A escolha da estratégia está diretamente ligada

às informações disponíveis no ambiente. Em um ambiente sem informações sobre a carga das

máquinas ou estatísticas de duração de execução de processos, o escalonador acaba optando

por estratégias simples que podem não trazer os melhores resultados. Ainda é possível a

combinação desses índices, para melhor representar o estado atual do sistema e obter assim

comportamentos mais próximos da realidade (ISHII 2004, p. 31).

A determinação dos índices como, consumo de memória, CPU e tempo de resposta

tem uma dependência muito forte com o ambiente, pois dependendo do processamento

disponível na máquina, 10% de CPU pode ser suficiente para executar várias tarefas,

enquanto em outros ambientes isto já pode ser inviabilizado, assim como, valores fixos podem

não ter bons resultados considerando que o necessário para executar o processo varia de

acordo com o processo.

A seguir são citadas políticas comuns, como a fairness, genetic algorithm scheduling,

throughput, turnaround e shortest job first.

2.4.1 Fairness

A política fairness considera que todos os processos devem ter o mesmo tipo de

tratamento. Com isso, todas as requisições vão para uma fila onde o primeiro a entrar é o

primeiro a sair. É uma política de fácil implementação, considerando que basta programar

uma fila FIFO.

2.4.2 Genetic Algorithm Scheduling

A política genetic algorithm scheduling (GAS) visa manter a utilização dos recursos

sempre no maior nível possível de acordo com primitivas informadas. Estas primitivas podem

ser relativas ao consumo de CPU, memória, disco, entre outros fatores. Caso a primitiva

informada seja ultrapassada, o escalonador pode iniciar novas máquinas e nelas novos

servidores ou, caso não seja possível iniciar nova máquina, pode aguardar até que o nível de

utilização dos recursos diminua em alguma máquina. Neste caso, enquanto o uso dos recursos

não diminui, mesmo que existam aplicações servidoras ociosas, elas não recebem requisições

Page 26: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

25

até que o nível de recursos da máquina esteja dentro do permitido; caso a média de uso dos

recursos esteja muito baixa, o escalonador pode encerrar uma máquina.

Segundo Senger (2004, p. 153), devido à quantidade de fatores existentes, a busca por

um servidor considerado ideal para executar o processo pode demorar muito tempo. Por isto,

em geral são utilizadas heurísticas para encontrar uma solução aceitável, onde o benefício da

busca pelo servidor aceitável compense o tempo levado pela busca.

2.4.3 Throughput

A estratégia throughput visa garantir que uma determinada quantidade de requisições

seja atendida em uma determinada quantidade de tempo. Definindo-se uma meta de

requisições por tempo, o escalonador irá distribuir as requisições existentes entre os serviços

existentes, e caso verifique que não irá conseguir executar a quantidade definida ele inicia um

novo serviço. Assim como, caso esteja executando muito mais requisições que a meta, o

escalonador pode encerrar um serviço.

Esta estratégia se utilizada sozinha pode gerar resultados indesejáveis, pois em

períodos de pico de utilização, caso o valor seja maior que o informado no throughput, o

escalonador pode manter o throughput e gerar uma fila grande. Assim como, em períodos de

pouca utilização pode ocorrer de processos sequer ficarem na fila e logo serem executados

para tentar alcançar o throughput quando não era necessário.

2.4.4 Turnaround

A estratégia turnaround visa garantir que o tempo total de execução de uma requisição

não seja maior que o configurado. Ao verificar que existem serviços que ainda não foram

executados e estão com o tempo próximo do limite, o escalonador pode iniciar um novo

serviço para conseguir executar as requisições a tempo. Caso esteja executando as requisições

em tempo muito menor que o tempo mínimo, o escalonador pode, da mesma forma, encerrar

um serviço iniciado.

É uma política que pode ser utilizada quando o tempo limite de execução for relativo

ao processo, pois conforme mencionado anteriormente, existem processos que necessitam ser

executados o mais rápido possível, enquanto outros podem aguardar algum tempo até serem

executados.

Page 27: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

26

2.4.5 Shortest Job First

A estratégia shortest job first visa garantir que as próximas tarefas a serem executadas

serão as que levarão menos tempo. Para isso é necessário saber, antes de executar a

requisição, quanto tempo aproximadamente ela levará. É uma estratégia que é interessante ser

executada em conjunto com outras estratégias, pois se utilizada exclusivamente, as tarefas que

levam mais tempo teriam tendência a levar muito tempo para serem executadas, ou mesmo

não serem executadas (SHYAM, 2014, p. 170).

2.5 RABBITMQ

RabbitMQ é um message broker e gerenciador de filas que permite o envio e

recebimento de mensagens entre aplicações, sendo uma implementação do protocolo

Advanced Message Queuing Protocol (AMQP). Segundo o RabbitMQ (2016), o RabbitMQ

foi desenvolvido na linguagem de programação Erlang, tendo seu desenvolvimento iniciado

em 2006, e a primeira versão liberada foi em 2007 através de uma licença Mozilla Public

License (MPL).

O RabbitMQ suporta o envio de mensagens através de fila e através de esquema de

publicação e inscrição, sendo que o RabbitMQ é composto basicamente por um servidora,

bibliotecas cliente para a comunicação com o broker que estão disponíveis em diversas

linguagens, incluindo Java, C# e Python, e uma plataforma para plug-ins adicionais para

complementar a utilização do RabbitMQ através de recursos adicionais. Estes plug-ins são

criados pela comunidade e são apenas publicados no site do RabbitMQ.

2.6 TRABALHOS CORRELATOS

Nesta seção são apresentados dois trabalhos correlatos ao trabalho proposto. Na seção

2.4.1 é apresentado o serviço da Amazon de controle de instâncias, o Amazon Auto Scaling

(AAS) e na seção 2.4.2 é apresentado a aplicação de previsão de instâncias da Netflix, o

Scryer.

2.6.1 AAS

O AAS é uma aplicação da Amazon que verifica as informações de utilização das

instâncias e aumenta/diminui a quantidade de instâncias do Amazon Elastic Compute Cloud

(EC2). Ele permite valores fixos de instâncias, permite ajustar quantidade de instâncias de

acordo com horários de pico e permite configurações de aumento automático de acordo com

as informações obtidas das instâncias (AMAZON WEB SERVICES, 2015).

Page 28: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

27

A configuração de ajuste automático de instâncias se baseia em regras criadas que

aumentam ou diminuem as instâncias de acordo com gatilhos. Estes gatilhos são disparados

pelo WatchCloud de acordo com algumas regras que consideram algumas métricas padrões

como utilização de CPU, memória, dentre outros. Porém também é possível que a aplicação

publique métricas através do uso de anotações do Java.

É possível identificar na Figura 10 um exemplo de configuração de alerta, onde foi

configurado que caso a média de utilização de CPU seja maior ou igual a 80% por pelo menos

cinco minutos é disparado o alarme.

Figura 10 – Configuração de alerta

Fonte: Amazon Web Services (2015).

Na Figura 11 é possível verificar a criação de uma política que aumenta em 30% a

quantidade de instâncias, ou pelo menos uma instância, quando um determinado alarme for

disparado.

Page 29: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

28

Figura 11 – Política de incremento de quantidade de instâncias

Fonte: Amazon Web Services (2015).

Uma das vantagens do AAS é a documentação existente da Amazon. Uma

desvantagem é o fato de ser exclusivo para o ambiente Amazon, isto é, para utilizar o AAS é

necessário ser cliente da Amazon e hospedar sua aplicação na Amazon. Embora em muitos

casos hospedar a aplicação em serviços como o da Amazon seja interessante por questões de

redução de custos e não precisar lidar diretamente com o hardware, também tem algumas

questões como o fato de fazer com que todas as informações do seu sistema estarão

disponíveis na Amazon e desta forma, é necessário confiança na empresa.

2.6.2 Scryer

O Scryer é um sistema que verifica qual a quantidade de instâncias Amazon Web

Services (AWS) que são necessárias para responder as requisições dos clientes da Netflix. O

Scryer utiliza o raciocínio baseado em casos para prever padrões de utilização, com isso, é

possível iniciar a diminuição da quantidade de instâncias antes de elas ficarem ociosas, ou

iniciar novas instâncias antes de as atuais estarem sobrecarregadas (JACOBSON; YUAN;

JOSHI, 2013).

Através de um histórico de utilização, foi possível observar vários fatores como os

horários do dia em que a taxa de utilização costuma aumentar ou diminuir e uma estimativa

de quanto costuma variar, bem como os dias da semana que costumam ter mais acessos, etc.

Com estes dados, a Netflix desenvolveu algumas fórmulas para que a previsão seja o mais

próximo do real (JACOBSON; YUAN; JOSHI, 2013). Na Figura 12 é possível observar que o

Scryer se mostrou muito efetivo e consegue ter uma previsão de utilização próxima da real

utilização.

Page 30: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

29

Figura 12 – Comparação entre o consumo real e o previsto

Fonte: Jacobson, Yuan e Joshi (2013).

A Netflix está hospedada na Amazon e utiliza o AAS como rota de escape para o caso

de ocorrer algum evento não previsto ou caso as previsões estejam muito incorretas. É

possível observar na Figura 13 que a previsão do Scryer e a utilização conforme o AAS são

muito parecidas.

Figura 13 - Carga prevista e carga escalonada pelo AAS

Fonte: Jacobson, Yuan e Joshi (2013).

Page 31: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

30

3 DESENVOLVIMENTO

Neste capítulo são apresentadas as etapas do desenvolvimento do aplicativo. Na seção

3.1 são enumerados os principais requisitos do projeto desenvolvido. A seção 3.2 apresenta a

especificação do projeto com diagramas de casos de uso e de atividades. A seção 3.3 detalha a

implementação do aplicativo, destacando os principais pontos. Por fim, a seção 3.4 apresenta

os experimentos realizados e resultados obtidos.

3.1 REQUISITOS

O middleware desenvolvido deve:

a) exibir informações sobre os dispositivos de uso como % de uso de CPU e memória

livre dos dispositivos que iniciam aplicações (Requisito Funcional - RF);

b) adicionar as mensagens em uma fila, onde mensagens que executam rápido podem

não ser adicionados no final da fila (RF);

c) armazenar informações sobre os serviços executados, como o tempo de execução

(RF);

d) considerar o estado atual das máquinas (consumo de memória e CPU) ao

selecionar a máquina que irá tratar a requisição(RF);

e) utilizar a linguagem de programação C# (Requisito Não Funcional - RNF);

f) permitir a comunicação com clientes em linguagem C# e Java (RNF);

g) utilizar a ferramenta RabbitMQ (RNF).

3.2 ESPECIFICAÇÃO

A especificação do projeto foi representada através de diagramas Unified Modeling

Language (UML), utilizando a ferramenta Enterprise Architect. Foram elaborados os

digramas de atividades, modelo entidade relacionamento (MER), diagrama de arquitetura e

diagrama de classes e pacotes, sendo apresentados nas próximas seções.

3.2.1 Diagrama de Arquitetura

O sistema consiste em cinco agentes. Os agentes são as aplicações cliente, que são

responsáveis por gerar requisições e enviar para o middleware, outro agente é o middleware,

há também um agente responsável por iniciar as aplicações servidoras, denominado

AppStarter, além deste, há as aplicações servidoras responsáveis por processas as requisições,

e por fim a aplicação de monitoramento, responsável por exibir os índices monitorados. Estes

agentes estão representados na Figura 14.

Page 32: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

31

Figura 14 – Agentes do sistema e principais interações

3.2.2 Diagramas de atividades.

Foram criados diagramas de atividades pois são várias atividades e não é possível

visualizar tudo em apenas um diagrama. O primeiro diagrama é composto pelas atividades da

aplicação servidora, o segundo diagrama contêm as atividades da aplicação AppStarter, o

terceiro diagrama contém as atividades da aplicação Monitor, os demais diagramas contém as

atividades do Middleware.

Page 33: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

32

Figura 15 – Diagrama de atividades da aplicação servidora

A aplicação servidora após iniciar aguarda uma requisição e ao receber verifica o tipo

da requisição, caso seja -1 então a aplicação servidora finaliza-se e notifica o middleware,

caso o tipo da requisição seja 1 então a aplicação trata a requisição e retorna ao middleware o

resultado do processamento.

Page 34: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

33

Figura 16 - Diagrama de atividades da aplicação AppStarter

A aplicação AppStarter se registra, e após receber a confirmação inicia uma thread de

envio de informações de uso da máquina e outra thread de inicialização de aplicações. A

thread de inicialização de aplicações aguarda por uma mensagem para então verificar se o

tipo de aplicação está na lista de tipos válidos e então inicia uma aplicação do tipo. A

aplicação de inicializações implementada apenas inicia aplicações do tipo 1. Após isto

verifica se iniciou a aplicação retornando o status da inicialização ao middleware. A thread de

envio de informações de uso coleta as informações de uso da máquina e de quantidade de

processos executando e envia ao middleware.

Page 35: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

34

Figura 17 – Diagrama de atividades da aplicação Monitor

A aplicação de monitoramento se registra no middleware e após receber a confirmação

cria os gráficos e aguarda por mensagens com novas informações para adicionar aos gráficos.

Ao receber novas mensagens a aplicação verifica se já existe uma série para a informação:

caso não exista, cria; caso exista apenas adiciona a informação na série.

Figura 18 – Diagrama de atividades do Middleware: Envio de dados estatísticos

A thread de envio de dados estatísticos consiste em carregar a lista de dados

estatísticos a ser enviada, iterar sobre a lista de monitores registrados e enviar para cada

monitor registrado.

Page 36: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

35

Figura 19 – Recebimento de dados estatísticos

A thread de recebimento de dados estatísticos é composta por uma verificação se

recebeu alguma mensagem, ao receber a mensagem armazena os dados da mensagem, tanto

em memória, quanto na base de dados.

Figura 20 – Recebimento de novas requisições

A thread de recebimento de novas requisições verifica se recebeu alguma requisição,

após isto verifica se a requisição deve ser priorizada, caso deva ser priorizada adiciona na 10ª

posição da fila, caso contrário adiciona ao final da fila.

Page 37: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

36

Figura 21 – Registro de AppStarter

A thread de registro de AppStarter verifica se recebeu alguma requisição, ao receber

adiciona o AppStarter na lista de AppStaters.

Figura 22 – Registro de Monitores

A thread de registro de monitores verifica se recebeu alguma requisição, e então ao

receber adiciona o monitor da requisição em uma lista de monitores registrados.

Page 38: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

37

Figura 23 – Tratamento de requisições

A thread de tratamento de requisições consiste em uma verificação se recebeu alguma

mensagem, ao verificar que recebeu então retira a requisição da fila e verifica se existe

aplicação servidora iniciada, caso não existe então inicia uma e aguarda a mesma ficar ociosa.

Após ter uma aplicação servidora ociosa, marca ela como não ociosa e inicia uma nova thread

para tratar a requisição, enquanto a thread atual volta para o início do processo. A nova

thread envia a requisição para a aplicação servidora, aguarda o resultado do processamento e

após isto salva o tempo de execução na base e envia para a aplicação cliente o resultado do

processamento retornado pela aplicação servidora.

Figura 24 – Verificação da quantidade de aplicações servidoras

Page 39: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

38

A thread de verificação da quantidade de aplicações servidoras verifica a quantidade

de aplicações servidoras por tipo de requisição, caso seja menor que o mínimo então inicia

novas aplicações servidoras, caso seja maior que o máximo então encerra aplicações

servidoras, os valores mínimos e máximos são configuráveis, porém no diagrama estão

exemplificados como 8 e 10.

3.2.3 Modelo Entidade Relacionamento

Na Figura 25 está representado o modelo entidade relacionamento (MER) do

middleware.

Figura 25 – Modelo entidade relacional

A entidade Statistics representa uma extração dos dados de utilização de uma

máquina, cada aplicação de iniciação de aplicações envia medições periodicamente para o

middleware, que são salvas na base de dados. A entidade ExecutionTime representa um

tempo de execução de um serviço em determinada máquina, o mesmo é salvo pelo

middleware após a execução de cada serviço. A entidade Device representa uma máquina, e

a entidade Service um serviço, ambas entidades apenas são utilizadas por outras entidades.

3.3 IMPLEMENTAÇÃO

A seguir são mostradas as técnicas e ferramentas utilizadas e a operacionalidade da

implementação.

Page 40: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

39

3.3.1 Técnicas e ferramentas utilizadas

O middleware foi desenvolvido utilizando a linguagem de programação C#, no

ambiente de desenvolvimento Visual Studio 2015 Community. O Visual Studio é o ambiente

de desenvolvimento oficial da Microsoft, sendo a versão Community disponibilizada

gratuitamente para estudantes.

Foi utilizado o banco de dados SQL Server 2014 para armazenar dados estatísticos de

utilização. A versão Express do SQL Server foi escolhida por ser gratuita. Também foi

utilizada a biblioteca EntityFramework versão 6.1.3 da Microsoft para efetuar as operações no

banco de dados

Foi necessário efetuar uma instalação do produto RabbitMQ, para trabalhar como um

broker, e a versão escolhida foi a 3.6.0 por ser a última versão no início do período de

desenvolvimento. Esta biblioteca utiliza uma máquina virtual Erlang, por isto, é necessário

também instalar o software Erlang/OTP na versão 18.2.1. Além disto, foi necessário utilizar

bibliotecas nas aplicações que se comunicam com o broker, nos aplicativos desenvolvidos em

C# e Java foram utilizadas as bibliotecas do RabbitMQ cliente na versão 3.6.2, própria para

cada linguagem de programação.

Para abstrair a utilização da biblioteca nos aplicativos C# foi criada uma classe

auxiliar, denominada MessageUtils. Nessa classe foram abstraídas algumas funções, como o

envio e a leitura de mensagens. No Quadro 1 é apresentado o código responsável pelo envio

de mensagens e no Quadro 2 é apresentado o código responsável pelo recebimento de

mensagens.

Page 41: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

40

Quadro 1 – Envio de mensagens 1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

public static void PublishMessage(IModel channel, string queueName,

byte[] message, string id = null)

{

IBasicProperties prop = channel.CreateBasicProperties();

if (id == null)

{

prop.MessageId = "1";

}

else

{

prop.MessageId = id;

}

prop.ReplyTo = Environment.MachineName;

channel.BasicPublish(exchange: "",

routingKey: queueName,

basicProperties: prop,

body: message);

}

Na linha 4 é criado o conjunto de propriedades da mensagem, e na linha 5 é verificado

se a propriedade id é preenchida. Caso tenha sido preenchida então na propriedade

MessageId é informado o valor da propriedade id, caso contrário é informado o valor 1.

Na linha 14 é chamado o método BasicPublish passando o parâmetro exchange vazio,

pois o mesmo não está sendo utilizado. No parâmetro routingKey é passado o nome da fila

que se deseja informar, na propriedade basicProperties é passado as propriedades

recém criadas, e no campo body é passado a mensagem em si, em uma sequência de bytes.

Page 42: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

41

Quadro 2 – Recepção de mensagens 1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

if (!timeOut.HasValue)

{

timeOut = 600000; // 10 minutos?

}

int tickStart = Environment.TickCount;

int tickCurrent;

BasicGetResult message = null;

do

{

message = channel.BasicGet(queueResponse, false);

if ((message == null) && (sleep.HasValue))

{

Thread.Sleep(sleep.Value);

}

tickCurrent = Environment.TickCount;

} while ((message == null) && (tickCurrent - tickStart <

timeOut.Value));

if(message == null)

{

return null;

}

channel.BasicAck(message.DeliveryTag, false);

Message response = new Message()

{

Msg = message.Body,

Id = message.BasicProperties.MessageId,

DeliveryTag = message.DeliveryTag,

header = (Dictionary<string,

object>)message.BasicProperties.Headers

};

return response;

Na linha 10 é chamado o método BasicGet. Este método verifica se existe alguma

mensagem para ser recebida, e caso não existe retorna null. Desta forma é feito um loop caso

o método BasicGet retorne null continua no loop aguardando a mensagem, e caso tenha

sido informado um valor para aguardar no loop, é chamado o método Thread.Sleep com

o valor informado, que é em milissegundos. Após receber a mensagem, é chamado o método

BasicAck, para informar ao broker que a mensagem foi lida e pode ser retirada da fila.

Após isto é criado um objeto que representa uma mensagem, com as propriedades do corpo da

mensagem, a id da mensagem, a tag de identificação da mensagem e o seu cabeçalho.

3.3.1.1 Aplicação cliente

A aplicação cliente é a aplicação que inicia o ciclo de processamento. A aplicação

monta uma requisição e envia para o middleware, que consiste em três informações: um

campo do tipo String MessageID, que serve para identificar qual o tipo de requisição; um

cabeçalho onde deve ser adicionado o parâmetro queue com uma string que é o nome da fila

para onde o middleware irá retornar a resposta da requisição; e do corpo da mensagem que é

Page 43: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

42

um array de bytes. O Quadro 3 apresenta o código responsável pelo preenchimento destes

campos e publicação da requisição.

Quadro 3 – Preenchimento de campos para publicação da mensagem na aplicação cliente 1

2

3

4

5

6

7

8

9

10

Map<String, Object> headers = new HashMap<String, Object>();

headers.put("queue", clientQueue);

BasicProperties prop = new AMQP.BasicProperties.Builder()

.messageId("1").replyTo(cpuName).headers(headers)

.build();

try {

channel.basicPublish("", queueName, prop, msg.getBytes());

} catch (IOException e) {

e.printStackTrace();

}

Nas linhas 1 e 2 é montado o mapa do cabeçalho, e nas linhas 3, 4 e 5 é construído o

conjunto de propriedades do envio e na linha 7 é utilizada a função getBytes da própria

String para retornar os bytes da String, que contém o XML. Estes bytes são passadas para o

método basicPublish, responsável pela publicação da mensagem no canal.

O corpo da mensagem pode ser um arquivo XML ou JSON, entre outros padrões

existentes no mercado, pois o middleware não faz nenhum tratamento sobre o corpo da

mensagem, ou seja, a aplicação cliente deve enviar uma mensagem em um formato que a

aplicação servidora saiba tratar. Além disto, é possível que seja utilizada criptografia para

garantir a segurança da informação trafegada, porém, a encriptação e decriptação são

responsabilidades da aplicação cliente e servidora.

No sistema implementado, a aplicação cliente monta um objeto do tipo Nota, serializa

o mesmo para o formato XML através da API Marshaller do próprio Java, que retorna uma

String com o XML, descrito no Quadro 4, e transforma essa String em um array de bytes.

Com isto, na aplicação servidora torna-se necessário a partir dos array de bytes voltar ao

objeto serializado, isto foi implementado através da API Serialize do próprio .NET. É

importante que todo o ambiente utilize o mesmo charset para transformar a String em bytes, e

depois no servidor para transformar o array de bytes em String

Page 44: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

43

Quadro 4 – Criação e Serialização de Nota em formato XML. 1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

Nota nota = new Nota();

nota.setAprovar(true);

nota.setCnpjDestinatario("123456789");

nota.setCnpjEmissor("987654321");

nota.setNomeDestinatario("Dest");

nota.setNomeEmissor("Emissor");

nota.setValue(100);

JAXBContext context = JAXBContext.newInstance(Nota.class);

Marshaller m = context.createMarshaller();

m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

StringWriter writer = new StringWriter();

m.marshal(nota, writer);

String msg = writer.getBuffer().toString();

Na linha 9 é iniciado um objeto do tipo JAXBContext, que é um ponto de entrada

para a utilização da API JAXB, passando o parâmetro com a classe que será serializada. Na

linha 11 é criado o Marshaller responsável pela serialização e na linha 15 é chamado o

método responsável pela serialização. Nota-se que a saída não ocorre em um String

diretamente, porém em um StringWriter. Na linha 16 é retornado o Buffer do

StringWriter e posteriormente transformado o Buffer em String através do método

toString.

O cliente envia as mensagens através da ferramenta RabbitMQ, onde é necessário se

conectar ao Broker e enviar uma mensagem na fila denominada NEW_TASK, além da

mensagem é necessário enviar ao middleware o nome da fila onde a aplicação cliente irá

aguardar resposta. Enquanto isto, outra thread busca por respostas na fila pré-definida. Ao

receber uma resposta a mesma é enviada para a saída padrão do sistema, no caso o console do

Eclipse. O Quadro 5 apresenta o código responsável pela criação do consumidor de

mensagens, conforme apresentado no Quadro 6.

Quadro 5 – Criação do consumidor utilizado na leitura de respostas 1

2

3

4

5

6

7

8

9

10

11

12

consumer = new DefaultConsumer(channel) {

@Override

public void handleDelivery(String consumerTag,

Envelope envelope, AMQP.BasicProperties properties,

byte[] body) throws IOException {

long deliveryTag = envelope.getDeliveryTag();

System.out.println(new String(body));

channel.basicAck(deliveryTag, false);

}

};

channel.queueDeclare(clientQueue, false, false, false, null);

Na linha 1 é criado o Consumer, e nas linhas 2 a 11 é sobrescrito o método

handleDelivery, para tratar a entrega das mensagens. Na linha 6 é retornado a

Page 45: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

44

DeliveryTag da mensagem e na linha 9 é chamado o método basicAck passando a

DeliveryTag, este método envia ao broker uma notificação que a mensagem em questão

foi lida e pode ser retirada da fila.

Quadro 6 – Utilização do consumidor de mensagens 1 channel.basicConsume(clientQueue, consumer);

Na linha 1 é chamado o método basicConsume passando por parâmetros a fila que

será lida e o consumidor que irá tratar as mensagens. Este chamado irá retirar todas as

mensagens da fila no momento da chamada.

3.3.1.2 Aplicação servidora

Uma aplicação servidora é iniciada e recebe via parâmetro o nome da fila ao qual deve

ler requisições. Caso receba uma mensagem com o ID -1 e o texto STOP a aplicação

servidora deve retornar uma mensagem com o texto OK e se encerrar, caso contrário a

aplicação trata a requisição. No Quadro 7 é apresentado o código responsável pelo tratamento

das requisições pela aplicação servidora.

Page 46: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

45

Quadro 7 – Tratamento da requisição pela aplicação servidora 1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

Message response = broker.ReadMessage(channel, ServerQueueName, 50,

null, queueDeclaring);

String resp;

String msg = Encoding.UTF8.GetString(response.Msg);

if ("-1".Equals(response.Id) && "STOP".Equals(msg))

{

serviceActive = false;

resp = "OK";

}

else {

var reader = XmlReader.Create(ToStream(msg.Trim()), new

XmlReaderSettings() { ConformanceLevel = ConformanceLevel.Document });

nota nota = new XmlSerializer(typeof(nota)).Deserialize(reader)

as nota;

Thread.Sleep(20);

if (nota.aprovar)

{

resp = "APROVADA";

}

else

{

resp = "REJEITADA";

}

}

byte[] body = Encoding.UTF8.GetBytes(resp);

broker.PublishMessage(channel, ServerQueueName + "_response", body,

null, queueDeclaring);

Na linha 6 é verificado se a mensagem é para a aplicação ser encerrada ou não. Nas

linhas 12 a 14 é serializada a nota fiscal para o objeto novamente. Na linha 29 é enviada a

resposta para o middleware.

3.3.1.3 AppStarter

As aplicações denominadas AppStarter são aplicações que são localizadas nas

máquinas que podem iniciar aplicações servidoras, e ao iniciarem se registram no middleware

através do envio uma mensagem na fila REGISTER_STARTER. A mensagem consiste em

uma string, com uma lista separada por ;, sendo que na primeira posição é informado o nome

da máquina, e após isto os tipos de aplicação que o AppStarter está apto a iniciar, sendo este

tipo um string qualquer. A partir deste momento a aplicação aguarda por solicitações do

middleware para iniciar aplicações. No Quadro 8 é apresentado o código responsável por

iniciar a aplicação servidora.

Page 47: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

46

Quadro 8 – Inicialização de aplicação servidora 1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

System.Diagnostics.Process process = new System.Diagnostics.Process();

System.Diagnostics.ProcessStartInfo startInfo = new

System.Diagnostics.ProcessStartInfo();

startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;

string serverName = System.Environment.MachineName + "|" + types + "|"

+ serverid;

serverid++;

startInfo.FileName = cmdLine;

startInfo.Arguments = "-name:" + serverName + param;

process.StartInfo = startInfo;

try

{

if (process.Start())

{

processes.Add(new ServerApp()

{

process = process,

name = serverName,

pid = process.Id

});

ret = serverName + "|" + process.Id.ToString();

}

else

{

ret = "Não foi possível iniciar a aplicação, nenhuma

exceção foi lançada porém a aplicação não iniciou.";

}

}

catch (Exception ex)

{

ret = "Não foi possível iniciar a aplicação, mensagem de erro

retornada: " + ex.Message;

LogUtils.Exception(ex);

}

Na Linha 1 é criado um novo processo, que é um recurso nativo, próprio para iniciar

processos, sendo apenas necessário informar o caminho do arquivo a ser iniciado e os

parâmetros, o que é feito nas linhas 8 e 9. Na linha 20 é verificada a propriedade Id do

processo, que retorna o PID do processo.

Esta aplicação também é responsável por retornar ao middleware periodicamente

informações sobre o status de utilização da máquina atual, como % de utilização de CPU,

memória RAM livre e o indicador Thread Queue Length do Processador. A partir destas

informações o middleware está apto a decidir se um AppStarter tem condições ou não de

iniciar uma nova aplicação servidora. O código fonte responsável pela inicialização dos

contadores de performance é apresentado no Quadro 9. No Quadro 10 é apresentado o código

responsável por calcular o valor dos contadores de performance.

Page 48: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

47

Quadro 9 – Inicialização de contadores de performance 1

2

3

4

5

6

7

8

9

10

PerformanceCounter processorTime = new PerformanceCounter("Processor",

@"% Processor Time", @"_Total");

PerformanceCounter total_processor_queue = new

PerformanceCounter("System", "Processor Queue Length", "");

PerformanceCounter ram_avaliable = new PerformanceCounter("Memory",

"Available Bytes", "");

CounterSample a1 = processorTime.NextSample();

CounterSample b1 = ram_avaliable.NextSample();

CounterSample c1 = total_processor_queue.NextSample();

Nesta rotina é utilizada a classe PerformanceCounter, que é uma classe nativa

responsável por buscar valores dos contadores de performance publicados pelo Windows.

Estes contadores podem ser visualizados através do aplicativo "Monitor de Desempenho" no

Windows, sendo que todos os contadores utilizados são públicos e estão disponíveis pelo

menos desde o Windows 7.

Na Linha 1 é criado o contador de performance Processor\% Processor

Time\_Total, que é responsável por retornar a percentagem de utilização do processador,

uma média da utilização de todos os núcleos do processador. Na Linha 2 é criado o contador

de performance System\Processor Queue Length, que retorna o tamanho da fila do

processor, que é um indicador que complementa o uso do processador, pois por vezes o uso

do processador não está alto, porém a fila do processador está, isto geralmente é causado por

excesso de interrupções. Na Linha 3 é criado o contador Memory\Avaliable bytes,

que retorna a quantidade de memória livre.

São colhidas amostras iniciais através do método NextSample, utilizada

posteriormente para calcular os valores dos contadores de performance.

Page 49: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

48

Quadro 10 – Cálculo dos contadores de performance 1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

Thread.Sleep(1000);

CounterSample a2 = processorTime.NextSample();

CounterSample b2 = ram_avaliable.NextSample();

CounterSample c2 = total_processor_queue.NextSample();

int a = (int)CounterSample.Calculate(a1, a2);

int b = (int)(CounterSample.Calculate(b1, b2) / 1024 / 1024);

int c = (int)CounterSample.Calculate(c1, c2);

string time = DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss");

string statiscs = System.Environment.MachineName + "|" + time + "|" + a

+ "|" + b + "|" + c + "|" + pCount;

MessageUtils.PublishMessage(channel, MESSAGETYPE.STATISTICS.ToString(),

statiscs);

a1 = a2;

b1 = b2;

c1 = c2;

Nas linhas 3, 4 e 5 são colhidas novas amostras que são utilizadas para o cálculo do

valor real dos contadores, através do método Calculate, nas linhas 7, 8 e 9. Nas linhas 13

e 14 é formada o string de retorno, utilizando-se os valores calculados anteriormente.

A aplicação de inicialização também é responsável por verificar se as aplicações

servidoras ainda estão em execução, e caso não estejam mais deve informar ao middleware

(Quadro 11).

Quadro 11 – Verificação das aplicações ainda em execução 1

2

3

4

5

6

7

8

9

10

11

12

13

14

for (int i = 0; i < processes.Count(); i++)

{

processes[i].process.Refresh();

if (processes[i].process.HasExited)

{

MessageUtils.PublishMessage(channel,

MESSAGETYPE.UNREGISTER_SERVER.ToString(), processes[i].name);

processes.RemoveAt(i);

}

else

{

pCount++;

}

}

Na linha 3 é feito uma atualização das informações dos processos que estão em cache.

Na linha 4 é verificado se a aplicação ainda está executando e caso não esteja mais é enviado

ao middleware o nome da aplicação na fila UNREGISTER_SERVER. Após isto o processo é

retirado da fila. A variável pCount representa o somatório das aplicações que estão

inicializadas, e também é enviado ao middleware para ser monitorada.

Page 50: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

49

3.3.1.4 Aplicação de monitoramento

A aplicação de monitoramento implementada utiliza a biblioteca JFreeChart para

exibir em gráficos os indicadores de utilização das máquinas. A iniciação dos objetos gráficos

é representada no Quadro 12.

Quadro 12 – Criação dos gráficos com JFreeChart 1

2

3

4

5

6

cpudataset = new TimeSeriesCollection();

cpuchart = ChartFactory.createTimeSeriesChart("Monitor de %CPU",

"Hora", "% CPU", cpudataset, true, false, false);

final XYPlot plotcpu = cpuchart.getXYPlot();

cpurendered = new XYLineAndShapeRenderer();

plotcpu.setRenderer(cpurendered);

Na Linha 1 é criado o objeto que representa uma coleção de séries. Na linha 2 é criado

um gráfico do tipo série de tempo, que possui medições de tempos em tempos. Na linha 4 é

criado um plot, utilizado pelo renderizador criado na linha 5. Para cada gráfico é necessário

repetir estes passos, por isto todo o código é repetido cinco vezes, para o gráfico de consumo

de CPU, memória RAM livre, thread queue length, contador de processos e quantidade de

mensagens do middleware.

Após a criação das coleções de séries é necessário criar as séries, nos gráficos de CPU,

RAM, thread queue length e contador de processos. Cada série representa uma máquina que

está executando a aplicação de inicialização. No Quadro 13 é exibido o código responsável

pela criação das séries.

Quadro 13 – Criação de séries 1

2

3

4

dev.cpuSeries = new TimeSeries(deviceName);

cpudataset.addSeries(dev.cpuSeries);

cpurendered.setSeriesPaint(series.size(), colors[series.size()]);

cpurendered.setSeriesStroke(series.size(), new BasicStroke(1.1f));

Na linha 1 é criada a série de consumo de CPU. Na linha 2 a série criada é adicionada

a lista de séries. Nas linhas 3 e 4 são informadas configurações de renderização da série,

como cor da linha e espessura dos pontos. No Quadro 14 é exibido o código responsável pela

adição dos pontos no gráfico.

Quadro 14 – Adição de pontos em gráfico utilizando JFreeChart 1

2

3

4

if (deviceSeries == null) {

deviceSeries = createDeviceSeries(series, counters[0]);

}

deviceSeries.cpuSeries.add(s, Integer.valueOf(counters[2]));

Na linha 1 é recuperado a série do dispositivo que está sendo adicionado no gráfico. Na

linha 2 é feito uma verificação se já existe uma série para o dispositivo, caso não existe então

cria uma nova série na linha 3, adiciona a mesma no dataset na linha 4 e na linha 6 e 7 são

Page 51: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

50

configuradas opções de cor e espessura da linha. Na linha 11, independente de ser uma série

nova ou uma já existente, a medição atual é adicionada na série.

3.3.1.5 Middleware

O middleware é um aplicativo composto por um conjunto de threads, sendo que uma

delas é a thread de recepção de mensagens. A recepção das requisições consiste em se

conectar no broker e verificar se existe alguma nova mensagem na fila NEW_TASK. Quando o

broker retornar alguma mensagem, é verificada a fila e o tempo estimado de execução da

mensagem e a mesma é adicionada na fila. O Quadro 15 apresenta o código fonte responsável

pela adição da requisição na fila.

Quadro 15 - Adição de mensagens na fila 1

2

3

4

5

6

7

8

9

10

11

12

13

14

if ((msg.EstimedTime != 0) && (messages.Count > 20))

{

if ((messages[10].EstimedTime > msg.EstimedTime))

{

messages.Insert(10, msg);

}

else {

messages.Add(msg);

}

}

else

{

messages.Add(msg);

}

Nas linhas 1 e 3 são verificadas as condições para que a mensagem seja adicionada em

uma posição mais privilegiada da fila. Caso a fila de mensagens tenha mais de 20 mensagens,

o middleware verifica o tempo estimado de execução da requisição, que é composto pela

média do tempo que outras requisições do mesmo tipo levam para serem processadas. Caso

tenha algum tempo estimado e o mesmo seja menor que o tempo estimado de execução da 10ª

requisição, a requisição é coloca na 10ª posição da fila, caso contrário, a requisição é

adicionada ao final da fila. Desta forma, prioriza um pouco requisições cujo tempo estimado

de execução seja muito baixo, porém sem ficar sempre ordenando a lista de acordo com o

tempo de execução.

Outra thread do middleware é responsável por retirar mensagens da lista de

requisições, sempre na posição zero da lista, e encontrar uma aplicação servidora que esteja

apta a efetuar o processamento, e enviar para a mesma o devido processamento. No Quadro

16 é apresentado o código que verifica se uma máquina está apta a iniciar uma aplicação ou

executar uma requisição.

Page 52: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

51

Quadro 16 – Verificação se a máquina pode executar requisição 1

2

3

4

5

6

private Boolean MachineMayExecuteApp(String deviceName)

{

var statisticsData = StatisticsStorage.findData(deviceName);

return (statisticsData == null) || (statisticsData.stats.cpu <

80);

}

Na linha 3 são carregados os dados estatísticos da máquina em que a aplicação

servidora está sendo executada e na linha 4 é feito uma validação sobre a % de uso de CPU da

máquina. Este método é chamado tanto para verificar se uma aplicação de uma máquina pode

receber nova requisição quanto para iniciar nova aplicação em uma máquina.

Caso nenhuma aplicação servidora esteja registrada, o mesmo verifica se existe alguma

aplicação AppStarter registrada que possa iniciar uma aplicação do tipo desejado e que a

máquina que está rodando o AppStarter não esteja sobrecarregada. Caso encontre, então

solicita ao AppStarter a inicialização da aplicação, que consiste em uma mensagem para a

aplicação AppStarter com o ID do tipo de aplicação servidora a ser iniciada, e o middleware

aguarda a resposta, que consiste em uma lista, separada por ; com o nome da máquina, o tipo

de aplicação servidora, o número da aplicação servidora e o PID do processo. Desta forma, o

middleware já registra internamente que essa aplicação servidora está livre e que a fila para

receber as mensagens é composta pela concatenação do nome da máquina, tipo de aplicação e

o número.

Após encontrar uma aplicação servidora para processar a requisição, o middleware

então envia a requisição e calcula o tempo de execução da requisição. Este processo é

apresentado no Quadro 17.

Page 53: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

52

Quadro 17 – Envio de requisição e cálculo de tempo de execução 1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

int tickBefore;

try

{

tickBefore = Environment.TickCount;

server.StartChannel();

server.PublishMessage(server.name, message.message, message.id);

}

catch ( Exception ex)

{

System.Console.Out.WriteLine(ex.Message);

Queue(message);

server.iddle = true;

return;

}

Message resp = server.ReadMessage(server.name + "_response", 50);

int tickAfter = Environment.TickCount;

Thread t = new Thread(() => ExecutionTimeDAO.Insert(message.id,

server.machine, tickAfter - tickBefore));

t.Start();

using (IModel channel = message.Connector.StartChannel())

{

channel.BasicQos(0, 1, false);

message.Connector.PublishMessage(channel, message.sender,

resp.Msg, null);

}

server.iddle = true;

Na linha 1 é verificado o contador de Ticks do Windows, que é um número que é

incrementado a cada 1 milissegundo pelo próprio Windows. Na linha 17 é novamente

verificado o contador de Ticks e na linha 20 é subtraído o valor do segundo contador pelo

primeiro contador e isto resulta na quantidade de milissegundos que levou para executar a

operação. Este valor é salvo em uma tabela para depois ser utilizado para identificar o tempo

médio de outras requisições do mesmo tipo.

Após o retorno da resposta do processamento da requisição, o middleware verifica qual

o nome da fila que o cliente solicitou a resposta e então retorna ao cliente a resposta da

solicitação.

O middleware ao receber dados de utilização de máquinas armazena os mesmos na

base de dados e mantém o último registro de cada máquina em memória, para ser utilizado

pelas rotinas de iniciação de aplicações servidoras e de requisição. A cada 30 segundos, o

middleware lê a lista com os últimos dados de cada máquina e envia para as aplicações de

monitoramento abertas. As aplicações de monitoramento se registram através do envio de

uma mensagem com o texto REGISTERMONITOR, e a partir deste momento estão aptas a

receber as informações de monitoramento.

Page 54: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

53

Para garantir que exista uma quantidade de aplicações servidoras condizente com a

quantidade de requisições, o middleware possui uma thread que a cada segundo verifica

quantas requisições de cada tipo entraram neste segundo e quantas aplicações existem de cada

tipo, e então, verifica se é necessário iniciar novas aplicações ou se é possível remover

aplicações. No Quadro 18 é apresentado o código responsável pela lógica.

Quadro 18 – Verificação de quantidade de aplicações servidoras ativas 1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

foreach (KeyValuePair<string, int> entry in msgs)

{

int minServers = (int)Math.Truncate((double)(entry.Value /

minServersRatio));

int maxServers = (int)Math.Truncate((double)(entry.Value /

maxServersRatio));

minServers = minServers > 0 ? minServers : 1;

maxServers = maxServers > 0 ? maxServers : 1;

servers.TryGetValue(entry.Key, out serverNames);

if (serverNames != null)

{

if (serverNames.Count() < minServers)

{

StartServer(entry.Key, minServers -

serverNames.Count());

}

else if (serverNames.Count() > maxServers)

{

StopServer(entry.Key, serverNames.Count() -

maxServers);

}

}

}

Na linha 3 é calculado a quantidade mínima de aplicações necessárias, que consiste em

1 aplicação para cada n requisições na fila. Na linha 5 é calculado a quantidade máxima de

aplicações necessárias, que consiste em 1 aplicação para cada n requisições na fila. Os valores

para requisições mínimas e máximas estão configuradas no arquivo App.Config, nos

campos minServersRatio e maxServersRatio. Desta forma, enquanto a quantidade

de aplicações servidoras estiver dentro do limite não altera. Porém, se o número de aplicações

for menor que o mínimo é chamado o método StartServer. Caso o número de aplicações

seja maior que o máximo, é chamado o StopServer. Ambos os métodos recebem o tipo de

aplicação que deve iniciar ou encerrar e a quantidade.

A inicialização de uma aplicação servidora consiste na varredura dos AppStarter

registrados, onde é verificado se o AppStarter já está iniciando alguma aplicação e se os dados

de uso da máquina indicam que a máquina em questão está apta a iniciar uma nova aplicação

servidora. Este trecho de código é está ilustrado Quadro 19.

Page 55: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

54

Quadro 19 – Verificação de AppStarter apto a iniciar aplicação 1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

List<ServerInitiator> initiatorList;

ServerInitiator initiator = null;

initiators.TryGetValue(kind, out initiatorList);

if (initiatorList != null)

{

int i = 0;

while ((i < initiatorList.Count()) && (count != 0))

{

initiator = initiatorList[i];

if ((!initiator.initializing) &&

(MachineMayExecuteApp(initiator.machine)) &&

initiator.initializeServer(kind, this))

{

count--;

}

i++;

}

}

Na linha 3 é carregada a lista de AppStarter que iniciam aplicações do tipo que se

deseja abrir, então, na linha 7 a lista é iterada, e na linha 11 é chamado um método

responsável pela verificação se uma máquina pode ou não executar uma nova aplicação

servidora, que está representado no Quadro 16. Na linha 12 é chamado o método

initializeServer responsável por enviar uma mensagem ao AppStarter informando o

tipo de aplicação que o mesmo deve iniciar.

O encerramento de uma aplicação servidora consiste na varredura da lista de

aplicações servidoras abertas ociosas e então enviar uma mensagem com o id -1 e o texto

STOP.

3.4 RESULTADOS E DISCUSSÕES

Nesta seção são apresentados os resultados obtidos através dos experimentos

realizados com o middleware. A seção 3.4.1 apresenta os resultados obtidos quando

executado todo o ambiente em uma máquina, na seção 3.4.2 apresenta os resultados obtidos

quando executando o ambiente de forma dividida em duas máquinas. A seção 3.4.3 apresenta

uma discussão sobre os principais problemas enfrentados durante os testes de desempenho.

3.4.1 Execução em uma máquina

A execução em uma máquina foi realizado em um notebook pessoal. Inicialmente foi

inicializado o middleware e após isto o AppStarter e a aplicação de monitoramento, e em

seguida a aplicação cliente. Após a inicialização da aplicação cliente foi aumentado a

quantidade de threads gerando XML de notas fiscais de produto, e o resultado pode ser visto

na Figura 26 e na Figura 27.

Page 56: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

55

Figura 26 – Primeira parte dos gráficos de informações de uso do primeiro teste

Page 57: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

56

Figura 27 – Segunda parte dos gráficos de informações de uso do primeiro teste

Na Figura 26 é possível identificar que pouco após as 18h38min houve um aumento no

número de requisições novas e requisições processadas, da mesma forma, na Figura 27 há o

aumento na quantidade de processos. A quantidade de requisições processadas é raramente

igual á quantidade de novas requisições e sempre acabam ficando algumas mensagens na fila.

Conforme se aumenta a quantidade de requisições, é aumentada a quantidade de processos

tratando as requisições, mantendo os valores de novas requisições e requisições tratadas

sempre próximos.

Ao passar de 200 novas mensagens nota-se que o gráfico de Thread Queue Length

começa a sair do zero e oscilar, da mesma forma a quantidade de novas mensagens oscila

muito. Os dois fatores estão ligados, pois, embora a percentagem de uso da CPU esteja baixa,

existem threads que estão prontas para receber tempo de processamento, porém estão

aguardando na fila, ou seja, este parâmetro acaba influenciando negativamente na

performance do sistema.

Após passar de 250 novas mensagens, o middleware não consegue mais receber todas

as mensagens que o broker recebe, com isto, embora o número de novas mensagens não

aumente, o broker começa a acumular mensagens na sua fila, isto pode ser visto na Figura 28.

Page 58: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

57

Figura 28 – Fila de mensagens no broker e taxa de mensagens do primeiro teste

Na Figura 28 é possível identificar dois quadros: o quadro com a fila de mensagens e o

quadro com a taxa de mensagens. No primeiro quadro é possível verificar que existem

mensagens que acabam ficando na fila do broker, no caso do primeiro teste pouco mais de

100 mensagens acabaram ficando na fila do broker. No segundo quadro é possível identificar

as taxas de mensagens publicadas, mensagens entregues, mensagens reconhecidas e

mensagens recebidas.

Mensagens publicadas é o total de mensagens que foram enviadas para o broker do

RabbitMQ a partir de qualquer uma das aplicações. As mensagens entregues são as

mensagens que foram recebidas a partir do modo de subscrição, onde é registrado um

consumidor de mensagens e o mesmo consome mensagens em determinada fila. Já as

mensagens recebidas são mensagens obtidas através de uma chamada específica ao método

Get. As mensagens reconhecidas são todas as mensagens que a aplicação envia para o broker

confirmando o recebido de alguma mensagem, de qualquer um dos métodos.

No teste foram publicadas aproximadamente 200 mensagens por segundo, além disto,

são entregues 96 por segundo através dos métodos consumidores, 104 mensagens são

recebidas através dos métodos de recepção individual, e 207 mensagens tem o seu

recebimento confirmado. Os recebimentos confirmados consistem em uma mensagem de

confirmação sobre cada mensagem recebida, que é necessária tanto para mensagens recebidas

Page 59: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

58

através de consumidores como parar mensagens recebidas individualmente. O total de

mensagens trafegadas chega a aproximadamente 600 mensagens por segundo.

A taxa de mensagens baixa se deve, principalmente, pela utilização de uma máquina de

baixo processamento e pelo fato de utilizar várias filas diferentes, com mais de uma forma de

envio recebimento de mensagens e pelo fato de necessitar retornar a confirmação do

recebimento das mensagens. Além disto, com todas as aplicações na mesma máquina

sobrecarrega o cliente do broker.

No experimento realizado, a memória RAM teve pouca influência no resultado final,

pois havia memória sobrando e as aplicações utilizavam pouca memória, porém, dependendo

das aplicações sendo executadas, a memória disponível pode passar a ser um fator com maior

relevância, por isto a mesma foi mantida sobre monitoramento.

3.4.2 Execução em duas máquinas

A execução do ambiente em duas máquinas foi realizado em dois notebooks pessoais.

Inicialmente foi iniciado o middleware e o broker em um com nome PAULO-NOTE, após

isto, no mesmo notebook foi iniciada a aplicação AppStarter, porém, no arquivo de

configurações foi alterado o tipo de server que a aplicação inicia para um tipo não utilizado,

desta forma, a aplicação não iria iniciar nenhuma aplicação servidora, porém iria retornar os

dados de utilização da máquina. Foi iniciado também o aplicativo de monitoramento.

Com os preparativos em uma máquina feitos, foi iniciado na outra máquina, de nome

NOTE-REGINA, a aplicação AppStarter e a aplicação cliente. Após as aplicações iniciadas,

foram aumentadas as threads que simulam a geração de XML de nota fiscal de produto e os

resultados são exibidos na Figura 29 e na Figura 30.

Page 60: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

59

Figura 29 - Primeira parte dos gráficos de informações de uso do segundo teste

Page 61: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

60

Figura 30 – Segunda parte dos gráficos de informações de uso do segundo teste

No início do teste, a quantidade de threads foi sendo aumentada e conforme

aumentava mais mensagens eram recebidas pelo middleware e mais mensagens eram

processadas. A quantidade de mensagens processadas é, na maioria dos casos, igual á

quantidade de novas requisições, por isto não fica visível no gráfico, porém, em alguns

momentos é possível identificar os pontos azuis próximos aos amarelos, ou linhas azuis

entrelaçadas às amarelas.

Para os parâmetros “minQueueRatio” e “maxQueueRatio” foram configurados os

valores cento e cinquenta e cento e trinta, respectivamente. Isto significa que a cada cento e

cinquenta requisições deveria ter pelo menos uma aplicação servidora para processar, e a cada

cento e trinta poderia ter no máximo uma aplicação servidora. É possível ver na Figura 29 a

quantidade de requisições novas e na Figura 30 a quantidade de aplicações servidoras, desta

forma, consegue-se perceber que pouco após as 05h47min a quantidade de requisições

ultrapassou cento e cinquenta, e, pouco após as 05h47min a quantidade de processos subiu de

um para dois.

Pouco após as 05h48min, na Figura 30 é possível identificar que a quantidade de

processos caiu de três para dois e na Figura 29 é possível ver que a quantidade de novas

requisições ficou abaixo de duzentos e sessenta, ou seja, menos que duas vezes o valor

Page 62: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

61

configurado em “maxQueueRatio”, por isso, a quantidade de processos foi diminuída de 3

para 2.

Após 05h50min é possível verificar que a quantidade de novas requisições e de

requisições sendo tratadas manteve-se, isto pois mesmo aumentando significativamente a

quantidade de threads enviando requisições, não foi possível enviar mais requisições. Porém,

mesmo neste cenário já foi possível verificar uma quantidade relativamente boa de

requisições sendo enviadas e tratadas pelo broker. A Figura 31 apresenta a página de

gerenciamento do RabbitMQ, onde é apresentada uma visão geral do funcionamento do

broker.

Figura 31 – Fila de mensagens do broker e taxa de mensagens do segundo teste

Na Figura 31 é possível verificar que a fila de mensagens do broker fica quase vazia,

pois as mensagens estão sempre sendo lidas. Também é possível verificar a taxa de

mensagens. Neste teste foram publicadas em média 392 mensagens por segundo, 197

mensagens foram entregues através de consumidores, 196 foram recebidas através do método

de recepção individual e 393 mensagens de confirmação de recebimento de mensagens,

totalizando 1178 mensagens por segundo.

O resultado da taxa de mensagens no segundo teste é superior ao primeiro, devido à

divisão da carga de interações com o broker entre duas máquinas e ao fato de que o Thread

Queue Length não afetou tanto este ambiente, conforme pode ser visto na Figura 29.

Page 63: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

62

3.4.3 Principais dificuldades ao utilizar o RabbitMQ

Para utilizar o RabbitMQ, esperava-se que cada aplicação tenha apenas uma conexão

com o broker, e cada thread possua um canal de comunicação aberto a partir desta conexão

central. Porém, mesmo utilizando o RabbitMQ desta forma ainda ocorriam vários erros

incomuns. Um exemplo é o erro “The AMQP operation was interrupted: AMQP close-reason,

initiated by Application, code=200, text="Goodbye", classId=0, methodId=0, cause= /”, que

ocorria principalmente ao chamar o método IModel.basicGet ou

Connection.CreateModel.

Para tratar esta situação foi necessário implementar uma camada intermediária

responsável por verificar se houve exceções do RabbitMQ no canal de comunicação ou na

própria conexão, e caso houvesse então reiniciava a conexão ou canal de comunicação. Isto

em parte solucionou os erros na aplicação, porém aumentou a complexidade da aplicação e

comprometeu o desempenho. Embora não tenham sido gerados dados estatísticos dos erros,

foi percebido que era mais comum que os erros ocorressem quando a utilização de CPU

estava muito alta.

Em versões anteriores do middleware, um grande problema foi a utilização de CPU,

pois em alguns pontos não fazia sentido criar um Consumer para receber uma única

mensagem, desta forma, era necessário aguardar uma requisição individual. Nestes momentos

geralmente é realizado um loop sem chamar o método Thread.Sleep, ou passando um

valor muito baixo, pois é necessário que a resposta assim que disponível seja recebida.

Não chamar o método Sleep faz com que o processador continue executando sempre

as operações de verificação de condição (recebeu resposta ou mudança no estado de objeto) e

pula para próxima linha que volta para a verificação de condição, este processo fica

executando até que haja a mudança na condição, e isto demanda processamento e acaba

elevando o consumo de CPU.

Chamar o método Sleep dentro dos laços de verificação de condição com um valor

mais alto possibilita que o processador pare o processamento da thread em execução e atenda

novas threads ou processos, diminuindo o consumo de CPU, porém, se a resposta chegar

enquanto o método Sleep está executando é necessário aguardar o final da execução do

método, aumentando o tempo de tratamento da requisição. Com isso, foi identificado que em

alguns pontos foi necessário trocar performance por diminuição do consumo de CPU.

Page 64: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

63

CONCLUSÕES

Os resultados alcançados foram satisfatórios. A aplicação de envio de NF-e para

validação foi implementada, gerando um XML de uma nota e enviando para o middleware. O

middleware atingiu o objetivo de iniciar e encerrar aplicações de acordo com a demanda e

balancear a utilização entre as máquinas disponíveis, isto foi implementado impondo um

limite no uso de CPU das máquinas, e ao chegar neste limite o middleware não inicia novas

aplicações nesta máquina e envia para outra.

A aplicação de monitoramento também atingiu o objetivo, pois ajuda a acompanhar o

desempenho do sistema como um todo, não apenas do middleware, ajudando a compreender

os gargalos e pontos a melhorar do ambiente, exibindo informações de utilização da máquina

e informações de mensagens processadas, novas mensagens e mensagens que já estão na fila.

A utilização da biblioteca RabbitMQ no middleware trouxe ganhos ao agilizar e retirar

a necessidade de preocupação com as questões do tráfego de dados na rede, porém, gerou

vários problemas em relação a confiabilidade: a grande maioria das interações com o

RabbitMQ necessitou de tratamento de exceções.

Como limitação, destacam-se as oportunidades de melhoria apontadas no ítem 4.1,

como a previsão de períodos de pico e antecipação quanto ao levantamento de aplicações de

processamento, além disto, não há tratamento para mais de um middleware executando no

mesmo ambiente.

Conclui-se que o desenvolvimento deste trabalho possibilitou uma alternativa para a

utilização de middleware para escalonar aplicações e gerenciar uma fila de mensagens, em

conjunto com o RabbitMQ.

3.5 EXTENSÕES

Para extensões deste trabalho propõem-se:

a) a partir da quantidade de requisições prever períodos de pico de utilização e

inicializar aplicações antecipadamente;

b) ao encerrar um middleware, suas mensagens não devem ser perdidas e outro(s)

middleware(s) devem assumí-las;

c) melhoria no algoritmo de priorização de requisições;

d) implementar tempo máximo de uma requisição na fila;

e) implementação de segurança, garantindo a integridade e autenticidade das

mensagens trafegadas, além de garantir que somente aplicações permitidas possam

interagir com o mesmo.

Page 65: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

64

REFERÊNCIAS

AMAZON WEB SERVICES. (n.d.) 2015. Disponível em:

<http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/policy_creating.html>.

Acesso em: 19/10/2015

ABIRAMI, S.P.; RAMANATHAN, Shalini. Linear Scheduling Strategy for Resource

Allocation in Cloud Environment. International Journal on Cloud Computing: Services

and Architecture(IJCCSA),v.2, n.1, p. 9-17. Fev. 2012

BAKKEN, Dave. Middleware. Encyclopedia of Distributed Computing, Kluwer Academic

Press, 2003.

BERNSTEIN, Philip A. Middleware An architecture for Distributed System Services. CLR

93/6. Disponível em: <http://www.hpl.hp.com/techreports/Compaq-DEC/CRL-93-6.pdf>.

Acesso em: 03 abr. 2016

BLAIR, G; COULOURIS, G; DOLLIMORE, J; KINDBERG, T. Sistemas Distribuídos:

Conceitos e Projeto. São Paulo: Bookman Editora Ltda, 2013

CHAPPELL, David A. Enterprise Service Bus: Theory in Practice. O’Really Media Inc.

2004

EUGSTER, PATRICK TH.; FELBER, PASCAL A.; GUERRAOUI, RACHID;

KERMARREC, ANNE-MARIE. The Many Faces of Publish/Subscribe. ACM Computing

Surveys, Vol. 35, No. 2, June 2003, pp. 114–131.

HOHPE, Gregor; WOOLF, Bobby. Enterprise Integration Patterns: Designing, Building,

and Deploying Messaging Solutions. Addison-Wesley Professional, 2003

ISHII, Renato P. NBSP: Uma política de escalonamento network-bound para aplicações

paralelas distribuídas. 2004. Dissertação (Mestrado em Ciências da Computação e

Matemática Computacional) – Ciências de Computação e Matemática Computacional,

Instituto de Ciências Matemáticas e de Computação - ICMC-USP, São Carlos.

JACOBSON, Daniel; YUAN, Danny; JOSHI, Neeraj. Scryer: Netflix: The Netflix Tech Blog.

2013. Disponível em: <http://techblog.netflix.com/2013/11/scryer-netflixs-predictive-auto-

scaling.html>. Acesso em: 18 set. 2015

KRAKOWIAK, S. Middleware Architecture with Patterns and Frameworks. 2009.

Disponível em: <http://proton.inrialpes.fr/~krakowia/MW-Book/main-onebib.pdf>. Acesso

em: 18/09/2015

MACHADO, Rivaldo R. J. Desenvolvimento de um middleware para comunicação via

web services e sua aplicação em sistemas de aquisição de dados industriais. 2014. 37 f.

Dissertação (Mestrado em Ciências) – Curso de Pós-Graduação em Engenharia Elétrica e de

Computação,Universidade Federal do Rio Grande do Norte, Natal.

MACIEL, Rita S. P.; ASSIS, Semírames R. Middleware: uma solução para o

desenvolvimento de aplicações distribuídas. CienteFico. v.4, n.1, p. (n.d.). janeiro-junho.

2014. Disponível em: <

http://www.cin.ufpe.br/~dmrac/infras%20de%20software/I.8.Semiramis.Middleware.pdf>.

Acesso em: 22 set 2015

MAHMOUD, Qusay H. Middleware for communications. John Wiley & Sons Ltd,

England. 2004

Page 66: MIDDLEWARE COM ESCALONAMENTO DE APLICAÇÕESpericas/orientacoes/Escalonament... · soluções para integração entre Sistemas de Informação”. Entretanto muitas empresas encontram

65

MONSON-HAEFEL, Richard; CHAPPELL, David A. Java Messaging Service. O’Reilly

Media Inc. 2000

NF-E. (n.d.) 2015. Disponível em:

<http://www.nfe.fazenda.gov.br/portal/perguntasFrequentes.aspx?tipoConteudo=E4+tmY+O

Df4=>. Acesso em: 31 ago. 2015

NOVELL Java Message Service. 2004. Disponível em:

<http://www.novell.com/documentation/extend52/Docs/help/MP/jms/concepts/jms.html>.

Acesso em: 03 abr. 2016

RABBITMQ (n.d.) 2016 Disponível em: <http://www.rabbitmq.com/documentation.html>.

Acesso em: 29 mar. 2016

ROSENBAND, Daniel L. A Remote Procedure Call Library. 1997. Disponível em:

<http://web.mit.edu/6.033/1997/reports/dp1-danlief.html>. Acessado em: 03 abr. 2016

SENGER, Luciano J. Obtenção e Utilização do Conhecimento sobre Aplicações Paralelas

no Escalonamento em Sistemas Computacionais Distribuídos. 2002. Monografia

(Doutorado em Ciências) – Ciências de Computação e Matemática Computacional, Instituto

de Ciências Matemáticas e de Computação - ICMC-USP, São Carlos.

SENGER, Luciano J. Escalonamento de processos: uma abordagem dinâmica e incremental

para a exploração de características de aplicações paralelas. 2004. Tese (Doutorado em

Ciências) – Ciências de Computação e Matemática Computacional, Instituto de Ciências

Matemáticas e de Computação - ICMC-USP, São Carlos.

SHYAM, Radhe; NANDAL, Sunil K. Improved Mean Round Robin with Shortest Job First

Scheduling. International Journal of Advanced Research in Computer Science and

Software Engineering. v.4, n.7, p. 170-179. Jul. 2014

SORDI, José O. de; MARINHO, Bernadete de L. Integração entre Sistemas: Análise das

Abordagens Praticadas pelas Corporações Brasileiras. RBGN, São Paulo, v. 9, n. 23, p.78-93,

jan./abr. 2007

THIRUVATHUKAL, George K; KAYLOR, Joe. [2013]. Disponível em:

<http://books.cs.luc.edu/distributedsystems/issues.html>

VARELA, Matías Leandro. Congresso Argentino de Ciencias de la Computacion. 1, 2007,

Correntes e Resistência. Conceptos fundamentales de un Middleware y razones de su

importancia em el mundo de hoy. Argentina: Universidad Nacional del Nordeste. v. 1.