• Nenhum resultado encontrado

Análise comparativa entre arquitetura monolítica e de microsserviços

N/A
N/A
Protected

Academic year: 2021

Share "Análise comparativa entre arquitetura monolítica e de microsserviços"

Copied!
56
0
0

Texto

(1)

UNIVERSIDADE FEDERAL DE SANTA CATARINA DEPARTAMENTO DE INFORMÁTICA E ESTATÍSTICA

João Paulo Duarte Lucio

ANÁLISE COMPARATIVA ENTRE ARQUITETURA MONOLÍTICA E DE MICROSSERVIÇOS

Florianópolis 2017

(2)
(3)

João Paulo Duarte Lucio

ANÁLISE COMPARATIVA ENTRE ARQUITETURA MONOLÍTICA E DE MICROSSERVIÇOS

Monografia submetida ao curso de Sis-temas de Informação para a obtençăo do Grau de Bacharel em Sistemas de Informação.

Orientador: Prof. Frank Siqueira

Florianópolis 2017

(4)
(5)

João Paulo Duarte Lucio

ANÁLISE COMPARATIVA ENTRE ARQUITETURA MONOLÍTICA E DE MICROSSERVIÇOS

Esta Monografia foi julgada aprovada para a obtenção do Título de “Bacharel em Sistemas de Informação”, e aprovada em sua forma final pelo curso de Sistemas de Informação.

Florianópolis, 26 de setembro 2017.

Prof. Cristian Koliver Coordenador do Curso Banca Examinadora:

Prof. Leandro José Komosinski

Prof. Frank Siqueira Orientador

(6)
(7)

Dedico o desenvolvimento deste trabalho à minha família, amigos e colegas de tra-balho que apoiaram, suportaram, incenti-varam e me ispiraram em todas as etapas do projeto.

(8)
(9)

AGRADECIMENTOS

Sou eternamente grato à minha irmã, Bruna Kalinoski e ao meu cunhado, Markian Kalinoski, pelo incondicional apoio em todos os as-pectos sejam eles físicos, mentais e intelectuais e que se fazem presentes neste projeto. Também devo agradecer a minha querida mãe e querido pai, Sonia Duarte e João Batista Lucio, pelo apoio, paciência e prin-cipalmente por compreender minha ausência durante o período que estive focado no desenvolvimento deste trabalho. Agradeço meus gran-des amigos, Vitor Arins e Thiago Diniz, por serem grangran-des colegas de curso e fontes de inspiração, não só para este trabalho, mas para a vida profissional e pessoal. Por fim, agradeço Aquele à quem confio e acredito que, sem o Seu desejo, nada disto seria possível!

(10)
(11)

Refactoring is a disciplined technique for restructuring an existing body of code, al-tering its internal structure without chan-ging its external behavior. Its heart is a series of small behavior preserving trans-formations. Each transformation (called a ’refactoring’) does little, but a sequence of transformations can produce a signi-ficant restructuring. Since each refacto-ring is small, it’s less likely to go wrong. The system is also kept fully working af-ter each small refactoring, reducing the chances that a system can get seriously broken during the restructuring.

Mar-tin Fowler at refactoring.com as cited in: Lawrence Bernstein, C. M. Yuhas (2005) Trustworthy Systems Through Quantita-tive Software Engineering. p. 266

(12)
(13)

RESUMO

Com o intuito de agregar os exemplos didáticos existentes, enriquecer a fonte de pesquisa para o domínio de arquiteturas de software e apresen-tar testes reais mais expressivos entre a arquitetura de microsserviços e monolítica, este trabalho tem por objetivo demonstrar uma análise comparativa entre duas arquiteturas de software através de uma avalia-ção comparativa entre o desenvolvimento de uma aplicaavalia-ção monolítica de um sistema gerenciador de cinemas, escrito utilizando a linguagem Javascript, e uma aplicação idêntica utilizando a arquitetura orientada à microsserviços. Novas arquiteturas de desenvolvimento como micros-serviços ganham cada vez mais destaque nos campos de desenvolvi-mento, pesquisa e mercado tecnológico, e por isso, torna-se interessante traçar um comparativo entre os prós e contras encontrados entre as duas arquiteturas de desenvolvimento. A fim de estabelecer um comparativo fiel e didático, foram analisados dois protótipos idênticos em termos de funcionalidades sendo um orientado ao desenvolvimento monolítico e o outro, uma aplicação orientada à microsserviços, ambas escritas em Javascript sobre a plataforma NodeJs e utilizando banco de dados não-relacional. A construção do protótipo monolítico baseando-se em um projeto pré existente em microsserviços, evidencia características quantitativas, qualitativas e particularidades sobre o desenvolvimento em cada metodologia. Ambas aplicações foram submetidas à crité-rios de performance, quantidade de código escrito e análise estrutural e, à partir dos resultados obtidos, foram apresentados e comentados seus comparativos para facilitar a compreenção dos resultados obtidos e esperados. Considerando a singularidade das características de cada aplicação, as tecnologias envolvidas ou os aspectos de gestão mencio-nados, este trabalho, ao fazer um estudo comparativo entre estas duas arquiteturas pode auxiliar, seja uma organização em sue processo de tomada de decisão sobre a arquitetura a ser adotada em um projeto, seja profissionais da área de desenvolvimento de software, estudantes e entusiastas para terem um melhor entendimento de sua aplicabilidade. Como resultado obtido à partir dos testes realizados neste trabalho, foi observado que a arquitetura monolítica pode sim desempenhar uma melhor performance comparado ao microsserviço.

Palavras-chave: Microsserviços. Monolítico. Arquitetura de Soft-ware.

(14)
(15)

ABSTRACT

With the purpose of aggregating the existing didactic examples, en-riching the research source for the domain of software architectures and presenting more expressive real tests between the microservice and monolithic architecture, this work aims to demonstrate a comparative analysis between two software architectures through a comparative eva-luation between the development of a monolithic application of a ci-nema management system, written using the Javascript language, and an identical application using the microservice oriented architecture. New development architectures such as microservices are gaining more prominence in the fields of development, research and technological market, and it is therefore interesting to draw a comparison between the pros and cons found between the two development architectures. In order to establish a faithful and didactic comparison, two identical prototypes were analyzed in terms of functionalities being one orien-tated to the monolithic development and the other, a application ori-ented to the microservices, both written in Javascript on the platform NodeJs and using non- relational The construction of the monolithic prototype based on a pre-existing project in micro-services, shows quan-titative, qualitative and developmental characteristics in each methodo-logy. Both applications were submitted to performance criteria, written code quantity and structural analysis and, based on the obtained re-sults, their comparatives were presented and commented to facilitate the understanding of the obtained and expected results. Considering the uniqueness of the characteristics of each application, the techno-logies involved or the aspects of management mentioned, this work, when doing a comparative study between these two architectures can help, either an organization in the process of decision making about the architecture to be adopted in a project, be software development professionals, students and enthusiasts to have a better understanding of its applicability. As a result of the tests performed in this work, it was observed that the monolithic architecture can perform better than the microservice.

(16)
(17)

LISTA DE FIGURAS

Figura 1 Comparativo entre Monolítico e Microsserviços,

Adap-tado de (FOWLER, 2015) . . . 32

Figura 2 Visão geral do design da arquitetura do projeto em mi-crosserviços. Fonte: (RAMIREZ, 2017a) . . . 33

Figura 3 Arquitetura inicial das máquinas virtuais rondando mi-crosserviços. Fonte: (RAMIREZ, 2017b) . . . 35

Figura 4 Estrutura de diretórios do código em microsserviços . . . 41

Figura 5 Estrutura de diretórios do código monolítico . . . 41

Figura 6 Contagem de linhas da aplicação monolítica . . . 42

Figura 7 Contagem de linhas da aplicação em microsserviços . . . . 42

Figura 8 Plano geral de testes criados no JMeter . . . 44

Figura 9 Aggregate Report Monolítico . . . 44

Figura 10 Aggregate Report Microsservices . . . 45

Figura 11 Rancher Web Interface . . . 46

(18)
(19)

LISTA DE ABREVIATURAS E SIGLAS

SOA Service-Oriented Architecture . . . 21

RAML RESTful API Modeling Language . . . 26

API Application programming interface . . . 26

RAML RESTful API Modeling Language . . . 28

Iaas Infrastructure as a service . . . 36

VM Virtual Machines . . . 36

TI Tecnologia de Informação . . . 36

HTML Hypertext Markup Language. . . 37

JSON JavaScript Object Notation . . . 37

API Application Programming Interface . . . 37

FTP File transfer Protocol . . . 38

LDAP Lightweight Directory Access Protocol . . . 38

JDBC Java Database Connectivity . . . 38

HTTP Hypertext Transfer Protocol . . . 38

TCP Transmission Control Protocol . . . 38

API Application Programming Interface . . . 40

(20)
(21)

SUMÁRIO 1 INTRODUÇĂO . . . 21 1.1 PROBLEMA . . . 21 1.2 OBJETIVO . . . 22 1.2.1 Objetivos específicos . . . 22 1.3 JUSTIFICATIVA . . . 22 1.4 BENEFÍCIOS . . . 23 1.5 METODOLOGIA . . . 23 1.6 ORGANIZAÇÃO DO TEXTO . . . 23 2 FUNDAMENTAÇÃO TEÓRICA . . . 25 2.1 MONOLÍTICO . . . 25 2.1.1 Modelo de Implementação . . . 26 2.2 MICROSSERVIÇOS . . . 26 2.2.1 Modelo de Implementação . . . 27 2.3 ESCALABILIDADE . . . 28 3 PLANEJAMENTO DO EXPERIMENTO . . . 29 3.1 EXPERIMENTO MONOLÍTICO . . . 29 3.1.1 Design . . . 29 3.1.2 Arquitetura . . . 32 3.2 EXPERIMENTO MICROSSERVIÇO . . . 33 3.2.1 Design . . . 33 3.2.2 Arquitetura . . . 34 3.3 STACK DE DESENVOLVIMENTO . . . 35 3.3.1 Docker . . . 35 3.3.2 Rancher . . . 36 3.3.3 Docker Swarm . . . 36 3.3.4 NodeJs . . . 36 3.3.5 Mongo . . . 37 3.3.6 Express . . . 37 3.3.7 JMeter . . . 37 4 AVALIAÇÃO COMPARATIVA . . . 39

4.1 PLANO DE TESTES PARA AVALIAÇÃO COMPARATIVA 39 4.2 VANTAGENS E DESVANTAGENS . . . 39

4.2.1 Vantagens da arquitetura em Microsserviços . . . 39

4.2.2 Desvantagens da arquitetura em Microsserviços . . . . 40

4.3 ANALÍTICO DE CÓDIGO . . . 40

4.3.1 Estrutura de diretórios . . . 40

(22)

4.3.1.2 Avaliação . . . 41 4.3.2 Linhas de código . . . 42 4.3.2.1 Avaliação . . . 43 4.4 PERFORMANCE . . . 43 4.4.1 Teste de carga . . . 43 4.4.1.1 Monolítico . . . 44 4.4.1.2 Microsserviços . . . 45 4.4.1.3 Avaliação . . . 45 4.5 INFRAESTRUTURA . . . 45 4.5.1 Escalabilidade . . . 46 5 CONCLUSÃO . . . 49 5.1 TRABALHOS FUTUROS . . . 50 REFERÊNCIAS . . . 51

(23)

21

1 INTRODUÇĂO

Microsserviços estão atualmente ganhando muito destaque no mercado de desenvolvimento de software e sendo discutidos em posts, blogs, artigos, redes sociais, conferências e apresentações. Alguns céti-cos da comunidade ignoram o termo por acreditar que não há nada de novo, apenas uma repaginação da arquitetura SOA (Service-Oriented Architecture). Entretanto, o padrão de arquitetura orientado a micros-serviços, que surgiu com a finalidade de otimizar a escalabilidade, a im-plantação (deploy) e a gestão de equipes de desenvolvimento advindas de uma arquitetura monolítica, possui benefícios significativos especi-almente quando isso possibilita um desenvolvimento mais ágil, com im-plantação facilitada, arquitetura de múltiplas linguagens simultâneas, e melhor adaptada para o novo cenário constituído por aplicações em nuvem. /

1.1 PROBLEMA

Para entender o padrão de arquitetura orientado a microsservi-ços precisamos primeiramente estudar a arquitetura que era utilizada até então para a construção de aplicações, a chamada arquitetura mo-nolítica.

Quase todas as histórias bem sucedidas de mi-crosserviços começaram com um monólito que ficou muito grande e acabou sendo quebrado. E, quase todos os casos em que ouvi falar de um sistema que foi construído como um sistema de microsserviços a partir do zero, acabou com

sé-rios problemas. (FOWLER, 2010)

Arquitetura monolítica, relativo à monólito, refere-se ao modelo de desenvolvimento de uma aplicação dentro de uma única estrutura executável, onde o comportamento obtido no resultado final do seu desenvolvimento poderemos encontrar uma única entidade, compacta, indivisível e impenetrável, que posteriormente será executada.

(24)

22

1.2 OBJETIVO

Com o intuito de agregar os exemplos didáticos existentes, en-riquecer a fonte de pesquisa para o domínio de arquiteturas de soft-ware e apresentar testes reais mais expressivos entre a arquitetura de microsserviços e monolítica, este trabalho tem por objetivo demonstrar uma análise comparativa entre duas arquiteturas de software através de uma avaliação comparativa entre o desenvolvimento de uma aplicação monolítica de um sistema gerenciador de cinemas, escrito utilizando a linguagem Javascript, e uma aplicação idêntica utilizando a arquitetura orientada à microsserviços, destacando os pontos fortes e fracos dentro do modelo adotado para cada uma, assim como suas particularidades e cenários de melhor aplicabilidade.

Para fazer esta correlação serão executadas duas aplicações idên-ticas. Uma utilizando microsserviços e a outra com base na arquitetura monolítica. Serão destacados durante a sua construção cenários que apresentam vantagens e desvantagens, análises de performance e pro-cessos de implantação abordando aspectos de escalabilidade em nuvem.

1.2.1 Objetivos específicos

Como objetivo específico deste projeto, pretende-se demonstrar a comparação entre as duas arquiteturas tanto no âmbito de testes de desempenho quanto à realização de análises estruturais como quan-tidade de código escrito necessário e estrutura de projeto. Obtendo assim, como resultado final, dois projetos arquiteturais de funcionali-dades equivalentes para que eventualmente sirvam a toda a comunidade como guia auxiliar para a elaboração de novos projetos.

1.3 JUSTIFICATIVA

Hoje podemos encontrar diversas linhas de pensamento dentro da comunidade de software que criticam a arquitetura de microsser-viços como sendo uma renomeação para arquiteturas preexistentes, e não sendo constituída, portanto, de alguma originalidade. Percebemos a dificuldade de se obter clareza e solidez quanto às informações dis-poníveis na rede, bem como exemplos demonstrativos das arquiteturas supracitadas.

(25)

23

1.4 BENEFÍCIOS

Podemos ressaltar o benefício deste projeto como sendo uma contribuição à comunidade de desenvolvedores de software, bem como alunos e professores, quanto às diferenças observadas dentro dos dois paradigmas arquiteturais e também a disponibilização de ambos os pro-jetos desenvolvidos para que possam servir de guias para futuras im-plementações.

1.5 METODOLOGIA

Com a intenção de atingir os objetivos propostos, este trabalho adota uma metodologia de estudo de caso comparativo de dois sistemas com características funcionais semelhantes, cada um desenvolvido com abordagens, tecnologias e arquiteturas distintas.

1.6 ORGANIZAÇÃO DO TEXTO

Para uma melhor compreensão e separação dos conteúdos, este trabalho será organizado em 5 capítulos e um apêndice com um artigo do referente à esta monografia.

Depois da introdução realizada no primeiro capítulo, o capítulo 2 apresenta a fundamentação teórica com as definições das abordagens de desenvolvimento de software que serão adotadas no projeto e também descreve como são aplicados ambos os modelos de implementação.

O capítulo 3 é composto pelo planejamento do experimento, as formas de avaliação comparativas, bem como as arquiteturas que se-rão adotadas neste trabalho para avaliar o desenvolvimento dos dois sistemas.

O capítulo 4 contém as informações relacionadas ao resultado dos testes aplicados, bem como a avaliação dos sistemas e também a apresentação dos dados obtidos através das metodologias escolhidas no capít ulo anterior.

No quinto capítulo estão as conclusões obtidas através dos re-sultados deste trabalho e as sugestões para trabalhos futuros sobre o assunto em questão.

(26)
(27)

25

2 FUNDAMENTAÇÃO TEÓRICA

2.1 MONOLÍTICO

Em uma arquitetura monolítica, uma única aplicação é respon-sável por todos os processos. Ela apresenta a interface para interação com o usuário, acessa os dados persistidos no banco de dados, processa pedidos de clientes e todas as outras ações que a aplicação necessitar.

A aplicação monolítica é auto-suficiente e independente de outras aplicações de computação. A filosofia do projeto é que o aplicativo é responsável não apenas por uma determinada tarefa, mas pode também executar todos os passos necessários para completar uma macro função. Em Engenharia de Software, uma aplicação monolítica descreve uma aplicação de software que é projetada sem modularidade externa, ou seja, sem a preocupação de construir uma aplicação que possa vir a ser um módulo para uma outra aplicação. A modularidade é desejável, em geral, uma vez que suporta a reutilização de partes da lógica da aplicação e também facilita a manutenção, permitindo a reparação ou substituição de partes da aplicação sem a necessidade de substituição total. Entretanto, as aplicações monolíticas em geral podem optar por uma modularização interna.

A modularidade pode ser conseguida em graus diferentes por di-ferentes abordagens de modularização. Modularidade baseada em có-digo permite aos desenvolvedores reutilizar e reparar partes da aplica-ção, mas ferramentas de desenvolvimento são necessárias para executar essas funções de manutenção (por exemplo, a aplicação pode precisar ser recompilada). Modularidade baseada em objeto fornece o aplica-tivo como uma coleção de arquivos executáveis separados, que pode ser independentemente mantidos e substituídos sem reimplantar o aplica-tivo inteiro. Alguns recursos de mensagens de objetos permitem que aplicações baseadas em objetos sejam distribuídas em múltiplas plata-formas, por exemplo, o Microsoft COM+. Arquiteturas orientadas a serviços usam especificamente um padrão de comunicação e protocolos para comunicação entre módulos.

Dizer que um software é, de fato, um monólito implica em adotar uma perspectiva sobre o assunto. Por exemplo, um software pode não estar orientado à serviço e pode ser descrito como um monólito, embora também possa ser baseado em objeto e estar virtualmente distribuído.

(28)

26

2.1.1 Modelo de Implementação

A abordagem monolítica é demonstrada neste trabalho através de uma aplicação única que conterá os mesmos serviços implementa-dos no projeto desenhado com microsserviços, com as mesmas regras de negócio. Este modelo altamente acoplado nos obriga a subir todos os serviços simultaneamente a cada implantação. Utilizaremos o Ja-vascript como linguagem principal de programação, ShellScript para automação de algumas tarefas de implantação e outras linguagens de especificação de API, como o RAML. / /

2.2 MICROSSERVIÇOS

Um microsserviço é uma unidade de software autônoma que, juntamente com muitas outras, compõe uma grande aplicação. Ao dividir seu aplicativo em unidades pequenas, cada parte pode ser independentemente implantada e escalada; pode ser escrita por diferentes equipes de de-senvolvimento, em diferentes linguagens de pro-gramação; e pode ser testada individualmente. (STOIBER, )

O objetivo de otimizar a implantação de softwares modulares, com ciclos de vida independentes, foi o que fomentou o aparecimento do termo Microsserviços. Ao longo dos anos, este termo utizado para descrever este novo tipo de arquitetura foi se constituindo de caracterís-ticas semelhantes relativas à descentralização de linguagens, automação do processo de implantação, alinhamento ao negócio e organização de projetos e equipes.

O termo "Arquitetura de Microserviços"surgiu nos últimos anos para descrever uma maneira particular de projetar aplicativos de software como suítes de serviços implementáveis

independente-mente. Embora não haja uma definição

pre-cisa desse estilo arquitetônico, existem certas ca-racterísticas comuns em torno da organização, da capacidade comercial, implantação automati-zada, inteligência nas chamadas da interface do sistema e controle descentralizado de idiomas e

dados. (FOWLER, 2015)

(29)

27

carente de informações a seu respeito, causando certa estranheza, não deve ser menosprezado. Este novo design arquitetural para o desen-volvimento de software tem chamado muito a atenção e atraído muitos olhares dentro e fora da comunidade tecnológica. Dentre os desbravado-res do novo conceito estão, por exemplo, os gigantes do streaming Net-flix e Spotify, e um dos maiores provedores de nuvem e de e-commerce mundiais, a Amazon.

Os microsserviços são uma abordagem para sis-temas distribuídos que promovem o uso de servi-ços finamente granulado com seus próprios ciclos

de vida, que colaboram em conjunto. (

NEW-MAN, 2015)

Não temos como explicar devidamente o estilo microsserviços de se escrever um software sem compará-lo ao seu modelo antagônico, cha-mado monolítico. Aplicações web corporativas são basicamente consti-tuídas de um Frontend, que é a interface do usuário, um banco de dados, normalmente relacional, para a persistência dos dados e um Backend, que consiste basicamente de um servidor de aplicação com as regras de negócio. Este último, quando desenvolvido monoliticamente, para toda regra de negócio, função ou serviço que se deseja fazer qualquer modificação, pode repercutir em um processo mais custoso de teste e implantação de todos os outros serviços, embora ainda assim seja cons-truído de forma mais ágil. O fato de que todos os serviços são, em geral, escritos com a mesma linguagem, não possibilita usufruir o que cada uma delas tem de melhor a oferecer, porém facilita o intercâm-bio na manutenção do código de todos os serviços entre diversos times de desenvolvimento. Importante destacar que nesta aplicação toda a sua lógica para lidar com uma solicitação é executada em um único processo, o que pode conferir ao monólito uma grande vantagem em termos de processamento.

2.2.1 Modelo de Implementação

Esta nova abordagem será demonstrada neste trabalho através de uma suíte de pequenos serviços que se comunicarão através de requi-sições HTTP. Estes serviços serão construídos sobre as regras de negócio de um sistema gerenciador de uma rede de cinemas, onde cada serviço terá seu deploy independente e automatizado. Apenas um gateway será responsável por centralizar e reconhecer estes serviços. Embora pu-dessem ser escritos em diferentes linguagens, utilizaremos o Javascript

(30)

28

como linguagem principal de programação, ShellScript para automação de algumas tarefas de implantação e outras linguagens de especificação como o RAML. /

2.3 ESCALABILIDADE

Denomina-se escalabilidade horizontal a capacidade de aumentar o poder de processamento ou a capacidade de armazenamento de uma aplicação essencialmente criando réplicas ao invés de melhorar um ser-vidor pre-existente. Dessa forma, em vez de comprar um serser-vidor mais robusto e mover toda a carga para ele, o responsável pela aplicação pode comprar um servidor adicional e distribuir a carga horizontal-mente entre todos eles.

O escalonamento horizontal é usado quando existe a capacidade de executar simultaneamente múltiplas instâncias da aplicação em ser-vidores distintos. É necessário destacar que, para que isso ocorra, a aplicação necessita ser projetada para trabalhar de forma distribuída. Normalmente, é muito mais difícil ir de 1 servidor para 2 servidores, do que ir de 2 para 5, justamente pela complexidade de se projetar uma aplicação distribuída.

Em alguns casos esta abordagem pode se fazer necessária, por exemplo, para guardar sessões de autenticações em disco. A não ser que este disco possa ser compartilhado entre diversos servidores, a aborda-gem mais adequada seria o escalonamento vertical. Outros casos que demandariam a mesma necessidade seria o caso de armazenamento por blocos, e bancos de dados que não possam ser distribuídos.

Na escalabilidade vertical a forma de escalar a aplicação, em que se amplia o tamanho do servidor/contêiner com mais CPU e memória RAM ou com maior espaço de armazenamento em disco, pode ser menos apropriada, mas é necessária ou até mesmo a única opção em algumas situações. Este tipo de escalabilidade ainda hoje é a mais comum e a mais utilizada para suportar a maioria das aplicações do mercado.

(31)

29

3 PLANEJAMENTO DO EXPERIMENTO

Para o desenvolvimento dos projetos que embasam este trabalho é tomado como exemplo e modelo um projeto de um Sistema Gerenci-ador de Cinemas (RAMIREZ, 2017a), no qual são utilizados microsser-viços como arquitetura fundamental e cujo código foi disponibilizado publicamente na plataforma para compartilhamento de softwares de código livre, o Github. A partir deste trabalho foi desenvolvido um novo projeto com características funcionais idênticas, alterando-se ba-sicamente a sua arquitetura para torná-lo um monólito provido das mesmas funcionalidades. Estes projetos, após implementados, foram comparados em termos de performance, construção do código, infraes-trutura necessária e processos de implantação. Ao final do experimento será apresentado um resultado conclusivo sobre as duas plataformas.

A temática da aplicação de exemplo foi um Sistema de Geren-ciamento de Cinemas composto por cinco serviços principais. Temos o serviço de “Booking” responsável por efetuar a compra dos assentos para um determinado filme em uma sala de cinema específica e também fará a verificação de uma ordem de compra já efetuada. O serviço “Ci-nema Catalog” retornará a lista de todos os ci“Ci-nemas cadastrados, bem como efetuará buscas por cinemas específicos sendo realizadas tanto por identificadores únicos dos cinemas como por identificadores de ci-dade e filme. O serviço de notificação será chamado de “Notification Service” e este estará responsável por enviar ao usuário final a confir-mação da sua ordem de compra por email. Este serviço estará atrelado ao serviço de pagamento, “Payment Service”, encarregado de validar e recuperar as ordens de compra e que, por sua vez, estará vinculado ao serviço de compra “Booking”, previamente descrito. Por fim, o serviço de catálogo de filmes, denominado “Movies”, proverá a lista dos filmes cadastrados, dos lançamentos de filmes (premières) e a obtenção de um filme específico através do seu identificador.

3.1 EXPERIMENTO MONOLÍTICO

3.1.1 Design

Na aplicação monolítica, como os serviços estão agrupados den-tro de um mesmo projeto e os pontos de chamadas para a interface da aplicação foram agrupados em um mesmo arquivo de endpoints para

(32)

30

facilitar e ilustrar didaticamente a arquitetura da aplicação como de-monstrado no trecho de código que segue.

Algorítmos 3.1 – Arquivo da API monolítica

’ u s e s t r i c t ’ c o n s t s t a t u s = r e q u i r e ( ’ h t t p−s t a t u s ’ ) module . e x p o r t s = ( { r e p o } , app ) => { //BOOKING API app . p o s t ( ’ / b o o k i n g ’ , ( r e q , r e s , n e x t ) => { c o n s t v a l i d a t e = r e q . c o n t a i n e r . c r a d l e . v a l i d a t e P r o m i s e . a l l ( [ v a l i d a t e ( r e q . body . u s e r , ’ u s e r ’ ) , v a l i d a t e ( r e q . body . b o o k i n g , ’ b o o k i n g ’ ) ] ) . t h e n ( ( [ u s e r , b o o k i n g ] ) => { c o n s t payment = {

userName : u s e r . name + ’ ’ + u s e r . lastName , c u r r e n c y : ’ mxn ’ , number : u s e r . c r e d i t C a r d . number , c v c : u s e r . c r e d i t C a r d . cvc , exp_month : u s e r . c r e d i t C a r d . exp_month , exp_year : u s e r . c r e d i t C a r d . exp_year , amount : b o o k i n g . totalAmount , d e s c r i p t i o n : ‘ T i c k e c t ( s ) f o r movie $ { b o o k i n g . movie } , w i t h s e a t ( s ) $ { b o o k i n g . s e a t s . t o S t r i n g ( ) } a t t i m e $ { b o o k i n g . s c h e d u l e } ‘ } r e t u r n P r o m i s e . a l l ( [ makePuchase ( payment , v a l i d a t e ) , P r o m i s e . r e s o l v e ( u s e r ) , P r o m i s e . r e s o l v e ( b o o k i n g ) ] ) } ) . t h e n ( ( [ p a i d , u s e r , b o o k i n g ] ) => { r e t u r n P r o m i s e . a l l ( [ r e p o . makeBooking ( u s e r , b o o k i n g ) , P r o m i s e . r e s o l v e ( p a i d ) , P r o m i s e . r e s o l v e ( u s e r ) ] ) } ) . t h e n ( ( [ b o o k i n g , p a i d , u s e r ] ) => { r e t u r n P r o m i s e . a l l ( [ r e p o . g e n e r a t e T i c k e t ( p a i d , b o o k i n g ) , P r o m i s e . r e s o l v e ( u s e r ) ] ) } ) . t h e n ( ( [ t i c k e t , u s e r ] ) => { c o n s t p a y l o a d = O b j e c t . a s s i g n ( { } ,

t i c k e t , { u s e r : {name : u s e r . name + u s e r . lastName , e m a i l : u s e r . e m a i l } } ) r e p o . s e n d E m a i l ( p a y l o a d ) . t h e n ( i n f o => { r e s . s t a t u s ( s t a t u s .OK) . j s o n ( t i c k e t ) } ) . c a t c h ( n e x t ) } ) . c a t c h ( n e x t ) } ) app . g e t ( ’ / b o o k i n g / v e r i f y / : o r d e r I d ’ , ( r e q , r e s , n e x t ) => { r e p o . g e t O r d e r B y I d ( r e q . params . o r d e r I d ) . t h e n ( o r d e r => { r e s . s t a t u s ( s t a t u s .OK) . j s o n ( o r d e r ) } ) . c a t c h ( n e x t ) } ) //MOVIES API app . g e t ( ’ / movies ’ , ( r e q , r e s , n e x t ) => { r e p o . g e t A l l M o v i e s ( ) . t h e n ( m o v i e s => { r e s . s t a t u s ( s t a t u s .OK) . j s o n ( m o v i e s ) } ) . c a t c h ( n e x t ) } ) app . g e t ( ’ / m o v i e s / p r e m i e r e s ’ , ( r e q , r e s , n e x t ) => {

(33)

31 r e p o . g e t M o v i e P r e m i e r s ( ) . t h e n ( m o v i e s => { r e s . s t a t u s ( s t a t u s .OK) . j s o n ( m o v i e s ) } ) . c a t c h ( n e x t ) } ) app . g e t ( ’ / m o v i e s / : i d ’ , ( r e q , r e s , n e x t ) => { r e p o . g e t M o v i e B y I d ( r e q . params . i d ) . t h e n ( movie => { r e s . s t a t u s ( s t a t u s .OK) . j s o n ( movie ) } ) . c a t c h ( n e x t ) } ) //CINEMA−CATALOG API app . g e t ( ’ / c i n e m a s ’ , ( r e q , r e s , n e x t ) => { r e p o . g e t C i n e m a s B y C i t y ( r e q . q u e r y . c i t y I d ) . t h e n ( c i n e m a s => { r e s . s t a t u s ( s t a t u s .OK) . j s o n ( c i n e m a s ) } ) . c a t c h ( n e x t ) } ) app . g e t ( ’ / c i n e m a s / : c i n e m a I d ’ , ( r e q , r e s , n e x t ) => { r e p o . getCinemaById ( r e q . params . c i n e m a I d ) . t h e n ( cinema => { r e s . s t a t u s ( s t a t u s .OK) . j s o n ( cinema ) } ) . c a t c h ( n e x t ) } ) app . g e t ( ’ / c i n e m a s / : c i t y I d / : movieId ’ , ( r e q , r e s , n e x t ) => { c o n s t params = { c i t y I d : r e q . params . c i t y I d , m o v i e I d : r e q . params . m o v i e I d } r e p o . g e t C i n e m a S c h e d u l e B y M o v i e ( params ) . t h e n ( s c h e d u l e s => { r e s . s t a t u s ( s t a t u s .OK) . j s o n ( s c h e d u l e s ) } ) . c a t c h ( n e x t ) } )

//NOTIFICATION SERVICE API

app . p o s t ( ’ / n o t i f i c a t i o n / s e n dE m ai l ’ , ( r e q , r e s , n e x t ) => { c o n s t v a l i d a t e = r e q . c o n t a i n e r . c r a d l e . v a l i d a t e v a l i d a t e ( r e q . body . p a y l o a d , ’ n o t i f i c a t i o n ’ ) . t h e n ( p a y l o a d => { r e t u r n r e p o . s e n d E m a i l ( p a y l o a d ) } ) . t h e n ( ok => { r e s . s t a t u s ( s t a t u s .OK) . j s o n ( { msg : ’ ok ’ } ) } ) . c a t c h ( n e x t ) } ) app . p o s t ( ’ / n o t i f i c a t i o n /sendSMS ’ , ( r e q , r e s , n e x t ) => { c o n s t { v a l i d a t e } = r e q . c o n t a i n e r . c r a d l e v a l i d a t e ( r e q . body . p a y l o a d , ’ n o t i f i c a t i o n ’ ) . t h e n ( p a y l o a d => { r e t u r n r e p o . sendSMS ( p a y l o a d ) } ) . t h e n ( ok => { r e s . s t a t u s ( s t a t u s .OK) . j s o n ( { msg : ’ ok ’ } ) } ) . c a t c h ( n e x t ) } )

//PAYMENT SERVICE API

app . p o s t ( ’ / payment / makePurchase ’ , ( r e q , r e s , n e x t ) => { c o n s t { v a l i d a t e } = r e q . c o n t a i n e r . c r a d l e

v a l i d a t e ( r e q . body . paymentOrder , ’ payment ’ ) . t h e n ( payment => { r e t u r n r e p o . r e g i s t e r P u r c h a s e ( payment ) } ) . t h e n ( p a i d => { r e s . s t a t u s ( s t a t u s .OK) . j s o n ( { p a i d } ) } ) . c a t c h ( n e x t ) } ) f u n c t i o n makePuchase ( paymentOrder , v a l i d a t e ) {

(34)
(35)
(36)

34

estrutura específica denominada “API Gateway”, conforme pode ser ob-servado na Figura 2, será utilizada para gerenciar os serviços que es-tarão disponíveis. Este serviço reconhecerá e disponibilizará as rotas dos serviços que estiverem a ela conectados. A classe do programa responsável por estas tarefas está demonstrada no exemplo à seguir.

Algorítmos 3.2 – Arquivo da API em microsserviços

’ u s e s t r i c t ’ c o n s t Docker = r e q u i r e ( ’ d o c k e r o d e ’ ) c o n s t d i s c o v e r R o u t e s = ( c o n t a i n e r ) => { r e t u r n new P r o m i s e ( ( r e s o l v e , r e j e c t ) => { c o n s t d o c k e r S e t t i n g s = c o n t a i n e r . r e s o l v e ( ’ d o c k e r S e t t i n g s ’ ) c o n s t d o c k e r = new Docker ( d o c k e r S e t t i n g s ) c o n s t g e t U p s t r e a m U r l = ( s e r v i c e D e t a i l s ) => { c o n s t { P u b l i s h e d P o r t } = s e r v i c e D e t a i l s . E n d p o i n t . Spe c . P o r t s [ 0 ] r e t u r n ‘ h t t p : / / $ { d o c k e r S e t t i n g s . h o s t } : $ { P u b l i s h e d P o r t } ‘ } c o n s t addRoute = ( r o u t e s , d e t a i l s ) => { r o u t e s [ d e t a i l s . Spe c . Name ] = { i d : d e t a i l s . ID , r o u t e : d e t a i l s . Spe c . L a b e l s . a p i R o u t e , t a r g e t : g e t U p s t r e a m U r l ( d e t a i l s ) } } d o c k e r . l i s t S e r v i c e s ( ( e r r , s e r v i c e s ) => { i f ( e r r ) { r e j e c t ( new E r r o r ( ’ an e r r o r o c c u r e d l i s t i n g c o n t a i n e r s , e r r : ’ + e r r ) ) } c o n s t r o u t e s = new Proxy ( { } , { g e t ( t a r g e t , key ) {

c o n s o l e . l o g ( ‘ Get p r o p e r t i e s from −> " $ { key }" c o n t a i n e r ‘ ) r e t u r n R e f l e c t . g e t ( t a r g e t , key ) } , s e t ( t a r g e t , key , v a l u e ) { c o n s o l e . l o g ( ’ S e t t i n g p r o p e r t i e s ’ , key , v a l u e ) r e t u r n R e f l e c t . s e t ( t a r g e t , key , v a l u e ) } } ) s e r v i c e s . f o r E a c h ( ( s e r v i c e ) => { addRoute ( r o u t e s , s e r v i c e ) } ) r e s o l v e ( r o u t e s ) } ) } ) } module . e x p o r t s = O b j e c t . a s s i g n ( { } , { d i s c o v e r R o u t e s } ) 3.2.2 Arquitetura

Neste formato arquitetural implantaremos cada serviço de forma independente, podendo escalá-los entre as três máquinas virtuais (doc-ker machines), conforme apresenta a Figura 3, disponibilizadas para tal. Nesta arquitetura também é importante destacar a presença de um serviço que até então não foi necessário para a concepção do

(37)
(38)

pro-36

(VMs).

Em outras palavras, o Docker nos permite construir imagens para a geração de contêineres que contenham uma “máquina virtual” onde podemos implantar uma aplicação e instalar todas as suas dependências e executá-lo como um processo isolado, compartilhando o kernel com outros contêineres no sistema operacional hospedeiro ou em qualquer plataforma IaaS.

/ /

3.3.2 Rancher

Rancher é uma plataforma de gerenciamento para contêineres Docker desenvolvido e distribuido pela Rancher Labs. Ele inclui uma distribuição Kubernetes, bem como a opção de escolher entre Docker Swarm e Apache Mesos. Todos eles usam o Docker como suporte de tempo de execução do contêiner subjacente e coordenam os contêine-res em execução entre múltiplos nós físicos discretos. Rancher também inclui serviços de infraestrutura modular, incluindo redes, balancea-mento de carga, descoberta de serviços, monitorabalancea-mento e recuperação. (RANCHER, )

3.3.3 Docker Swarm

Docker Swarm é uma ferramenta de agrupamento e agendamento para contêineres Docker. Com o Swarm, os administradores e desenvol-vedores de TI podem estabelecer e gerenciar um cluster de nós Docker como um único sistema virtual. /

3.3.4 NodeJs

Node.js é uma plataforma aberta, multiplataforma e um ambi-ente de tempo de execução de JavaScript para executar código em Ja-vaScript lado do servidor (NODEJS, ). Historicamente, o JavaScript foi usado principalmente para scripts do lado do cliente, nos quais os scripts escritos em JavaScript estavam incorporados em arquivos HTML de uma página Web para serem executados no lado do cliente por um ma-quina de JavaScript no navegador do usuário. O Node.js permite que o JavaScript seja usado para construir e executar os scripts JavaScript do lado do servidor para produzir conteúdo Web dinâmico antes que

(39)

37

a página seja enviada para o navegador da web do usuário. Conse-quentemente, o Node.js tornou-se um dos elementos fundamentais do paradigma “JavaScript em todos os lugares”, permitindo que o desenvol-vimento de aplicativos web se unisse em torno de uma única linguagem de programação, em vez de exigir o uso de linguagens diferentes para escrever scripts do lado do servidor e do lado do cliente. /

3.3.5 Mongo

MongoDB é um programa de banco de dados livre, aberto e multiplataforma . Classificado como um programa de banco de dados NoSQL, o MongoDB usa documentos similares a JSON com esquemas. O MongoDB é desenvolvido pela MongoDB Inc. e é publicado sob uma combinação da Licença GNU Affero General Public e da Licença Apache. /

3.3.6 Express

Express.js, ou simplesmente Express, é uma estrutura de aplica-ção web para o Node.js, lançado como software livre e de código aberto sob a Licença MIT. É projetado para a construção de aplicativos web e APIs. Na verdade, é a estrutura padrão do servidor para Node.js. /

O autor original, TJ Holowaychuk, descreveu-o como um servidor inspirado em Sinatra, o que significa que é relativamente mínimo com muitos recursos disponíveis como plugins. Express é a parte do backend da pilha MEAN, juntamente com a plataforma Node.Js, o banco de dados MongoDB e o framework para frontend AngularJS.

3.3.7 JMeter

O Apache JMeter é um projeto Apache que pode ser usado como uma ferramenta de teste de carga para analisar e medir o desempenho de uma variedade de serviços, com foco em aplicativos da web. Adap-tado de (APACHE, ).

JMeter pode ser usado como uma ferramenta de teste unitário para conexões de banco de dados JDBC, FTP, LDAP, Web Services, JMS, HTTP, conexões TCP genéricas e processos nativos do sistema operacional. Pode-se também configurar o JMeter como uma ferra-menta de monitoramento, embora este seja tipicamente considerado

(40)

38

apenas para teste em vez de monitoramento avançado. Ele também pode ser usado para alguns testes funcionais. / / / / /

O JMeter suporta parametrização de variáveis, asserções (vali-dação de resposta), cookies por segmento, variáveis de configuração e uma variedade de relatórios.

A arquitetura JMeter é baseada em plugins. A maioria dos re-cursos são implementados como plugins. Os usuários da ferramenta podem facilmente estender o JMeter desenvolvendo plugins personali-zados.

(41)

39

4 AVALIAÇÃO COMPARATIVA

4.1 PLANO DE TESTES PARA AVALIAÇÃO COMPARATIVA

As análises comparativas a serem aplicadas neste projeto consis-tem de comparações teóricas, analíticas e performáticas. As análises teóricas abordarão as comparações como vantagens e desvantagens en-tre as arquiteturas. Os testes analíticos apresentarão a estrutura de diretórios e as diferenças encontradas na estrutura organizacional dos projetos de maneira qualitativa e qualitativamente as linhas de código entre ambos os projetos. A performance obtida através da execução exaustiva entre os dois projetos será apresentada na parte de avaliação final deste capítulo. Por fim será demonstrado um comparativo entre a escalabilidade entre as duas arquiteturas.

Para a realização dos testes, o cenário utilizado foi constituído de máquinas virtuais semelhantes cujas configurações possuiam 2.19 GHz de processamento, 1.96 GiB de memória e 17.9 GiB de capacidade de armazenamento.

4.2 VANTAGENS E DESVANTAGENS

4.2.1 Vantagens da arquitetura em Microsserviços

Uma arquitetura baseada em Microservice di-vide sistemas de software em muitos pequenos serviços que podem ser implantados de forma

independente. Cada equipe trabalha em seus

próprios Microservices e, portanto, está desaco-plada de outras equipes. Isso permite escalar facilmente os processos ágeis. A modularização no Microservices protege o sistema contra a de-composição da arquitetura. Conseqüentemente, os sistemas baseados em Microservices perma-necem mantidos no longo prazo. Além disso, os sistemas legados podem ser migrados para Mi-croservices sem ter que alterar o código legado. Além disso, a entrega contínua é mais fácil de implementar em sistemas baseados em

(42)

40

- A aplicação inicia mais rápido, o que torna os desenvolvedores mais produtivos e acelera as implantações.

- Cada serviço pode ser implantado independentemente de outros serviços, portanto, é mais fácil implantar novas versões de serviços com maior freqüência.

- Desenvolvimento mais fácil de dimensionar e também pode ter vantagens de desempenho.

- Elimina qualquer compromisso a longo prazo com uma pilha de tecnologia. Ao desenvolver um novo serviço, você pode escolher uma nova pilha de tecnologia.

- Os serviços são geralmente melhor organizados, uma vez que cada microsserviço possui um trabalho muito específico e não se preo-cupa com os trabalhos de outros componentes.

- Os serviços desacoplados também são mais fáceis de recompor e reconfigurar para servir os propósitos de diferentes aplicativos (por exemplo, atendendo os clientes da web e a API pública).

/

4.2.2 Desvantagens da arquitetura em Microsserviços

- Os desenvolvedores devem lidar com a complexidade adicional da criação de um sistema distribuído.

- Complexidade de implantação. Na produção, há também a complexidade operacional de implantação e gerenciamento de um sis-tema composto por muitos tipos de serviços diferentes.

- À medida que você está construindo uma nova arquitetura de microsserviços, é provável que você descubra muitas preocupações transversais que você não antecipou em tempo de design.

4.3 ANALÍTICO DE CÓDIGO

4.3.1 Estrutura de diretórios

Para capturar a estrutura das pastas dos projetos apresentadas nas figuras 4 e 5, foi utilizada a biblioteca Tree, disponibilizada pelo

Centro de Computação biológica através do link: http://mama.indstate.edu/users/ice/tree .

(43)
(44)
(45)

43

4.3.2.1 Avaliação

Como a contagem de linhas refere-se tanto aos arquivos de código da aplicação propriamente dita quanto aos arquivos de configuração de ambiente, nota-se que microsserviços necessitou de pelo menos três vezes mais esforço de escrita de código. Devemos também considerar a necessidade da criação do serviço que atua como ponto único de acesso para a utilização de todos os outros serviços, o qual chamamos de “Gateway” e que possui aproximadamente trezentas e trinta linhas, como um segundo fator para a discrepância entre os valores obtidos.

4.4 PERFORMANCE

4.4.1 Teste de carga

Para poder comparar a performance entre ambas arquiteturas serão aplicados conjuntos de testes de carga (Figura 8) formados por requisições assíncronas através da ferramenta JMeter. As requisições aplicadas às duas implementações do sistema serão idênticas, contendo o mesmo número de threads para envio de requisições, de modo que possamos avaliar o comportamento das aplicações em iguais condições. Dentro deste conjunto de testes, teremos uma primeira bateria de testes responsáveis por buscar as agendas dos cinemas por cidade e identificadores únicos do filme (Fetch schedules by city and movieId). Em seguida um outra bateria de testes é realizada para buscar todos os cinemas de uma determinada cidade (Fetch cinemas by city). Outra sequência de testes trará os filmes de um determinado cinema através do seu identificador único. A seguir, uma tarefa de teste dará uma resposta de todos os filmes cadastrados e outra mostrará apenas os que possuem a propriedade “premiere”. A tarefa subsequente buscará os detalhes de um filme específico baseado no seu identificador único. Por fim, os dois últimos grupos de testes serão responsáveis por realizar a reserva, pagamento e notificação dos usuários e também retornar as reservas realizadas por um determinado usuário através do número do pedido.

Durante a execução dos testes foram criadas 1000 threads em cada teste pelo JMeter, a fim de estressar os serviços e assim conseguir obter métricas comparativas como tempo médio de resposta e a porcen-tagem de erros de requisição, bem como um gráfico da distribuição do

(46)
(47)
(48)
(49)
(50)
(51)

49

5 CONCLUSÃO

Para concluir os resultados obtidos a partir deste trabalho serão comentados os pontos fortes e fracos de cada arquitetura, bem como as avaliações obtidas. Na maior parte deste trabalho foram aborda-dos assuntos sobre a concepção de uma aplicação, seja ela monolítica ou em microsserviços. Porém, não podemos deixar de lembrar que o ciclo de vida de uma aplicação em um ambiente real vai muito além da sua construção propriamente dita. A arquitetura adotada para a concepção do projeto acabará por impactar em boa parte deste ciclo, desde as regras de negócios a serem suportadas, passando pelos testes de integração, implantação e principalmente a manutenção.

A partir destas considerações pode-se dizer que a arquitetura em microserviços destaca-se em grandes aplicações onde seus benefícios são facilmente identificados. O tempo de iniciação de um projeto é muito mais rápido, visto que cada serviço é independente. Isto faz com que os desenvolvedores ganhem maior agilidade, tanto no desenvolvimento quanto nas implantações. Com a mesma premissa de independência dos serviços, as liberações de versões dos serviços tendem a ser mais fre-quentes, e também é proporcinada aos projetistas uma maior precisão no dimensionamento de projetos e equipes.

Com módulos menores e independentes, a facilidade de trocar a pilha tecnológica composta em um serviço ou construir um novo ser-viço utilizando outra pilha tecnológica também podem ser identificadas como benefícios alcançados por esta arquitetura. A independência da linguagem utilizada em cada serviço também pode aferir ao projeto uma melhor performance, o que não foi observado nas análises e testes aplicados neste trabalho. Alguns especialistas também sugerem que o fato de que na composição de cada serviço tenha apenas funcionalidades específicas para o interesse do próprio serviço possa trazer mais orga-nização ao projeto, embora muitos serviços possam apresentar funções redundantes.

Serviços de baixo acoplamento também são mais fáceis para se-rem reaproveitados e reconfigurados para servir propósitos de diferentes soluções, por exemplo, atendendo uma aplicação web e fornecendo uma API pública.

Quanto à arquitetura monolítica, evidencia-se a vantagem de abstrair preocupações relacionadas ao reconhecimento e registro de no-vos serviços, visto que todos os serviços estarão dentro de um mesmo monólito, a limitação dos recursos de segurança, trilhas de auditoria,

(52)

50

proteção contra ataques de negação de serviço (DOS), e a conexão e comunicação entre os componentes da aplicação. Como vimos na apli-cação utilizada para fins de comparação, também podem haver vanta-gens de desempenho, já que o acesso à memória é mais rápido do que a comunicação entre processos.

/

5.1 TRABALHOS FUTUROS

A respeito dos trabalhos futuros relacionados a este tema, pose abordar temas em que outras arquiteturas de softwares posejam de-senvolvidas para traçar os respectivos demonstrativos e comparativos. Outra abordagem mais detalhista seria aprofundar-se no desenvolvi-mento de mais testes comparativos e também na especialização de uma das arquiteturas trabalhadas neste projeto. Além destes temas dire-tamente relacionados ao tema fundamental do projeto, este trabalho também abre portas para o desenvolvimento de aplicações distribuídas, utilização de contêineres, ferramentas de automação e gerenciamento de aplicações desenvolvidas utilizando-se microsserviços, entre outros.

(53)

51

REFERÊNCIAS

APACHE. JMeter. <http://jmeter.apache.org/>. Acessado em 03/06/2017.

DOCKER. What is Docker. <https://www.docker.com/>. Acessado em 13/05/2017.

FOWLER, M. MonolithFirst. Junho 2010.

<https://martinfowler.com/bliki/MonolithFirst.html>. Aces-sado em 8 mar. 2017.

FOWLER, M. Microservices, a definition of this new architectural term. Junho 2015.

<https://martinfowler.com/articles/microservices.html>. Acessado em 13/07/2017.

NEWMAN, S. Building Microservice. [S.l.]: OReilly, 2015. 473 p. NODEJS. NodeJs. <https://nodejs.org/en/>. Acessado em 03/06/2017.

RAMIREZ, C. Build a NodeJS cinema microservice and deploying it with docker part 1. 2017. <https://medium.com/@cramirez92/build- a-nodejs-cinema-microservice-and-deploying-it-with-docker-part-1-7e28e25bfa8b>. Acessado em 07/08/2017.

RAMIREZ, C. Deploy Nodejs microservices to a Doc-ker Swarm Cluster [DocDoc-ker from zero to hero]. 2017.

< https://towardsdatascience.com/deploy-a-nodejs-microservices-to-a-docker-swarm-cluster-docker-from-zero-to-hero-464fa1369ea0>. Acessado em 13/05/2017.

RANCHER. Rancher. <https://rancher.com/>. Acessado em 03/06/2017.

STOIBER, M. Build your first Node.js microservice.

<https://mxstbr.blog/2017/01/your-first-node-microservice/>. Acessado em 11/06/2017.

WOLFF, E. Flexible Software Architectures. [S.l.]: Leanpub, 2015. 324 p.

(54)
(55)
(56)

Referências

Documentos relacionados