Muito tem se falado sobre arquitetura de microserviços  ultimamente, principalmente após a publicação de Martin Fowler e James Lewis . Para quem ainda não está familiarizado com o termo, uma arquitetura de microserviços compreende uma maneira específica de se projetar software através de serviços independentes e autônomos no quesito implantação. Apesar de não existir uma definição precisa para este estilo de arquitetura, existem algumas características em comum em relação à organização da lógica de negócio, implantação automatizada, inteligência nas pontas e controle descentralizado de linguagem e informação (Fowler e Lewis, 2014).

Conceitos relacionados

Muitos autores argumentam que microserviço é apenas um sinônimo para a abordagem já há muito conhecida, mais precisamente conceituada em 1996, como  Arquitetura Orientada a Serviços , ou SOA (Service-Oriented Architecture), que se trata de uma abordagem arquitetural corporativa que permite a criação de serviços de negócio interoperáveis que podem facilmente ser reutilizados e compartilhados entre aplicações e empresas (Gartner Group, 1996).

Existe ainda um outro conceito conhecido como Filosofia Unix  que se trata do conjunto de normas e abordagens utilizadas por Ken Thompson e Dennis Ritchie durante e após o desenvolvimento do sistema operacional Unix e suas ferramentas. A Filosofia Unix se baseia em fazer programas muito específicos e que resolvam um determinado problema da melhor maneira possível , de forma que tais programas possam se comunicar entre si e serem combinados  de modo a contemplar tarefas mais complexas.

Com tais conceitos definidos, podemos dar sequência ao protótipo funcional que foi desenvolvido para exemplificar uma implementação de arquitetura de microserviços (ou SOA).

Protótipo funcional

Para fins de demonstração prática e aplicação dos conceitos descritos acima, foi desenvolvido um protótipo que comporta a arquitetura de microserviços e contempla os seguintes artefatos:

  •  Duas aplicações funcionais que utilizam os microserviços implementados
    • Blog
    • Fórum
  • API RESTful
  • CloudAMQP (serviço cloud gratuito que fornece uma instância de RabbitMQ )
  • Três microserviços com persistências individuais
    • Accounts (cadastro de contas e controle de autenticação)
    • Posts (cadastro de publicações)
    • Comments (cadastro de comentários)

Diagrama da arquitetura do protótipo desenvolvido

 

Detalhes da arquitetura

Como pode ser observado no diagrama da arquitetura, a comunicação entre os artefatos se dá através de dois protocolos:

  • HTTP (Hypertext Transfer Protocol): Protocolo de transferência de hipertexto. Base da  comunicação de dados utilizado na Web;
  • AMQP (Advanced Message Queuing Protocol): Protoco avançado de enfileiramento de mensagens;

O protocolo AMQP permite a troca de mensagens assíncronas entre diferentes aplicações e/ou serviços . O software mais popular que implementa um servidor de AMQP é o RabbitMQ. Para o protótipo, foi utilizado um serviço cloud chamado CloudAMQP, que fornece instâncias de RabbitMQ e possui um plano gratuito que permite a troca de até 1 milhão de mensagens mensais.

Existem várias formas de se beneficiar do protocolo AMQP:

  • Envio simples de mensagem de um serviço A para um serviço B (sem resposta);
  • Enfileiramento de mensagens de um serviço A para um serviço B (sem resposta);
  • Publicação/Inscrição que permite o envio de uma mensagem para vários consumidores;
  • Roteamento;
  • Tópicos (uso avançado de Publicação/Inscrição);
  • RPC (Remote Procedure Call), chamada de procedimento remoto ;

Para entender o protótipo basta compreendermos a última forma de uso, RPC.

As bibliotecas que encapsulam a chamada de procedimento remoto (RPC), geralmente são projetadas de forma que o uso seja transparente e intuitivo, aparentando ser uma mera chamada de função, quando de fato, está sendo feita a comunicação via AMQP para um serviço remoto e sendo aguardado o recebimento da resposta. Portanto, o uso de RPC ocorre quando um software efetua uma chamada de um serviço para outro software via AMQP e aguarda a resposta .

No momento em que este artigo é escrito, o protótipo se encontra desenvolvido inteiramente em JavaScript (Node.js), tanto as aplicações clientes quanto os microserviços. Porém, em um futuro próximo, para tornar o exemplo mais rico, os microserviços serão reescritos em outras linguagens e plataformas como Ruby, Python, PHP e Java. Dessa forma mais bibliotecas de integração com AMQP serão cobertas pelo protótipo.

Descrição do protótipo

Para executar o protótipo em sua própria máquina siga as instruções contidas no leia-me do repositório (link ao final do artigo), o restante do artigo será focado em explicar o fluxo do protótipo.

O cenário esperado para que o protótipo seja utilizado compreende os seguintes requisitos:

  • Ao menos uma instância iniciada de cada microserviço;
  • API RESTful iniciada;
  • Instância de RabbitMQ iniciada (através do serviço CloudAMQP);
  • Aplicações clientes iniciadas (Blog e Fórum);

Com o cenário devidamente preparado, as aplicações clientes (Blog e Fórum) podem ser utilizadas normalmente.

Para fins de exemplificação, vamos analisar o fluxo de mensagens que ocorre ao visualizar uma publicação na aplicação Blog:

  1. A aplicação Blog efetua uma requisição para a API RESTful para obter a publicação;
  2. A API efetua uma RPC para o microserviço Posts para obter a publicação;
  3. O microserviço Posts busca a publicação em sua persistência e responde a chamada RPC que recebeu;
  4. A API recebe a resposta do microserviço Posts e responde a requisição inicial da aplicação Blog;

Observando um caso isolado como o fluxo acima, não é muito perceptível o benefício que a arquitetura de microserviços tem a oferecer, pois apenas foram criadas mais camadas entre a requisição HTTP e a persistência. O real benefício neste caso, é que este é apenas um dos fluxos que ocorrem ao se visualizar uma publicação no Blog. Além de se obter a publicação, também são obtidos o perfil do autor da publicação e os perfis dos autores de cada comentário existente na publicação através dos microserviços Accounts e Comments. Ou seja, vários microserviços trocam mensagens entre si quando uma publicação é visualizada no Blog.

Em outras palavras, o uso de uma arquitetura de microserviços permite à um sistema robusto uma maior resistência a falhas e um maior potencial de escalabilidade , uma vez que cada microserviço pode ser escalável individualmente conforme a necessidade da aplicação. A resistência a falhas se encontra na capacidade que o sistema possui de continuar funcionando normalmente ainda que um ou mais microserviços se tornem indisponíveis.

Alguns podem estar se perguntando qual a real necessidade da API RESTful, visto que as aplicações finais (Blog e Fórum) poderiam se comunicar diretamente com os microserviços através do CloudAMQP. De fato a API RESTful não é necessária, a camada da API foi criada apenas para simplificar a comunicação e expor uma interface HTTP para os microserviços que até então estariam disponíveis somente por AMQP/RPC. Com uma API RESTful expondo os microserviços, as aplicações finais podem utilizar requisições HTTP para consumir os serviços, permitindo dessa forma a criação de aplicações finais que por alguma restrição de tecnologia não sejam capazes de utilizar o protocolo AMQP.

Vale lembrar que a RPC através do AMQP utiliza o algoritmo de Round-Robin para efetuar as chamadas das instâncias de dado serviço, isto é, a cada nova chamada, o RabbitMQ envia a mensagem para a próxima instância que encontrar do serviço. Portanto, para escalar um dado serviço, basta levantar novas instâncias que o RabbitMQ já irá lidar com o balancemanto das mensagens.

Monitoramento dos microserviços

Outro benefício da arquitetura de microserviços utilizando AMQP é a capacidade de monitorar a utilização de cada serviço de forma atômica e em tempo real, o que permite o acesso a mais informações sobre a performance e sobre a necessidade de escalabilidade.

Segue um exemplo das filas que foram criadas para as aplicações do protótipo e do monitoramento em tempo real a partir do painel fornecido pelo serviço CloudAMQP.

Visualização das filas. Painel fornecido pelo CloudAMQP

 

Monitoramento do envio de mensagens entre os microserviços

 

Conclusão

Não podemos reduzir toda a problemática de arquitetura de software a uma questão do que é certo e errado ou bom e ruim, pois cada caso possui suas muitas variáveis e circunstâncias que devem ser consideradas e seus muitos cenários e ambientes distintos possíveis em que o software em questão pode atuar.

Com esta premissa em mente, vamos analisar quais as vantagens e desvantagens que uma arquitetura de microserviços pode oferecer, levando-se em consideração que não se tratam de verdades absolutas, apenas conclusões teóricas baseada em uma das muitas formas possíveis de se implementar microserviços através de AMQP.

  • Vantagens
    • Escalabilidade a nível atômico
      • cada ação/serviço do software pode ser escalado individualmente, tirando-se portanto um maior proveito da capacidade de hardware existente;
    • Manutenibilidade
      • cada microserviço pode possuir processos organizacionais independentes, desde sua concepção à sua implantação, portanto o esforço dos recursos humanos pode ser melhor aproveitado;
    • Reutilização
      • um mesmo microserviço pode ser consumido por várias aplicações diferentes, diminuindo drasticamente o tempo de desenvolvimento de novas aplicações que possuírem recursos semelhantes;
    • Resistência à falhas
      • caso um microserviço se torne indisponível ou falhe, somente os recursos que dependam diretamente dele serão comprometidos nas aplicações finais;
    • Flexibilidade de tecnologia
      • como o protocolo AMQP se comporta como a lingua franca entre os microserviços, nada impede que cada microserviço seja desenvolvido em uma linguagem ou plataforma diferente, o único requisito é que o microserviço ou aplicação em questão seja capaz de se comunicar com os demais;
  • Desvantagens
    • Perda de performance
      • este é um ponto muito subjetivo, depende muito de como a arquitetura for implementada e utilizada, mas de forma geral, caso a arquitetura seja homogênea no quesito comunicação como o caso do protótipo, as aplicações finais tendem a perder performance devido à adição de novas camadas entre o usuário final e a lógica do negócio;
    • Difícil implantação
      • principalmente no início da implementação de uma arquitetura de microserviços, até que toda a infraestrutura seja preparada e o processo de cada microserviço seja definido e padronizado, a velocidade de implantação de novos recursos e aplicações tende a ser reduzida drasticamente;

Links e referências