Desenvolvimento

21 mar, 2017

Implemente uma arquitetura baseada em microsserviço no Bluemix – Parte 01

Publicidade

As arquiteturas de microsserviço permitem criar aplicativos em nuvem mais resilientes e escaláveis. Aplicativos são particionados em vários serviços que se comunicam conforme necessário usando APIs bem definidas.

Nesta série de artigos, mostraremos como implementar aplicativos baseados em microsserviço usando apps Cloud Foundry (CF) e contêineres IBM no IBM Bluemix. A Parte 01 foca nos apps CF.

Nosso aplicativo de amostra é criado usando o padrão de arquitetura de microsserviço e é uma loja de e-commerce simples que vende armações para óculos. O app de amostra destina-se apenas a fins de demonstração e não representa código de qualidade de produção. No entanto, ele efetua showcase de uma base de código simples para explorar microsserviços.

O app de amostra consiste de dois microsserviços:

  • cat gerencia o catálogo de produtos;
  • cart gerencia um carrinho de compras exclusivo para cada sessão do navegador.

A interface com o usuário cliente gerencia a interface com o usuário da web para compras. No momento, não há microsserviço para envio, gerenciamento de inventário ou gerenciamento de conta. Todos esses serviços podem ser desenvolvidos futuramente sem afetar nossa abordagem de implementação.

Neste artigo, criaremos nosso aplicativo de compras baseado em microsserviço usando apps CF. Artigos posteriores nesta série mostrarão como criar o mesmo aplicativo usando contêineres IBM para Bluemix.

Software que você precisa para este artigo

Cada microsserviço é implementado em Python e usa a microestrutura Flask. Eu escolhi Python e Flask, pois eles possuem os pacotes e imagens de construção necessários. Python e Node.js serão úteis se você desejar modificar o servidor e o código de UI depois de obtê-los do repositório git.

Introdução a microsserviços

Arquiteturas de aplicativos são desenvolvidas para atender às demandas de usuários e alavancar a computação em nuvem. Os usuários esperam que seus apps estejam disponíveis em tablets, em smartphones e no navegador. Esses apps precisam manipular interfaces com o usuário por toque e teclado/ mouse. Atualizações em apps são procuradas com mais frequência do que atualizações em software tradicional e simples. Como resultado, o desenvolvimento de aplicativos da web simples e monolíticos para navegadores de desktop não é mais suficiente.

Os padrões de design de software distribuído e o conceito de um “sistema de sistemas” estão sendo aplicados em aplicativos baseados em nuvem. O padrão de arquitetura de microsserviço refere-se à implementação de um aplicativo ou serviço como um conjunto de partes independentes (“microsserviços”). Cada microsserviço está limitado ao escopo e é criado para escala, conforme necessário, com uma API bem definida exposta para uso de clientes.

Para desenvolvedores, as vantagens de um padrão de arquitetura de microsserviço incluem:

  • Os desenvolvedores podem gerenciar versões e implementar componentes de aplicativos (microsserviços) separadamente;
  • Os desenvolvedores podem trabalhar em microsserviços separados em equipes pequenas e ágeis;
  • Os desenvolvedores podem aplicar uma cultura DevOps de liberações contínuas, upgrades contínuos e testes A/B de microsserviços;
  • Eles podem focar no estabelecimento de contratos entre componentes de interação, já que as arquiteturas de microsserviço são inerentemente centralizadas na API com loose coupling, mas com alta coesão.

O gateway de API: um padrão comum para microsserviços

O padrão de gateway de API direciona um problema fundamental com arquiteturas de microsserviço, que é como clientes de um aplicativo baseado em microsserviço acessam os serviços individuais:

Considere um aplicativo móvel que forneça a experiência do usuário para uma loja de e-commerce como a Amazon. Digamos que a loja de e-commerce seja implementada usando microsserviços. Na exibição de uma única página de produto, o aplicativo móvel deveria interagir com diversos microsserviços, como:

  • Catálogo de produto
  • Inventário
  • Revisões do cliente
  • Conta do usuário
  • Carrinho de compras

Cada microsserviço expõe um terminal de API, assim, nosso app móvel terá os diversos terminais que precisa para renderizar sozinho uma tela de produto.

Agora, o que ocorre se quisermos refatorar um microsserviço? Como o cliente móvel se comunica com cada microsserviço diretamente, esse cliente móvel precisa ser atualizado sempre que modificamos a API de um microsserviço. Isso causa complexidade adicional ao realizar push de atualizações para todos os dispositivos que usam o cliente móvel.

O padrão de gateway de API aborda esta complexidade: em vez de o cliente móvel interagir diretamente com cada microsserviço, um gateway de API é criado. Isso atua como uma forma de controlador frontal — de um único ponto lógico de entrada no aplicativo.

Para desenvolvedores e arquitetos, o padrão de gateway de API fornece essas vantagens:

  • Separa a API lógica exposta para clientes da implementação física de vários microsserviços;
  • Fornece um único ponto de entrada para todos os clientes. Os clientes só precisam saber o local do gateway de API e não o local de cada microsserviço individual implementado;
  • Permite que o arquiteto forneça APIs específicas de função com base no tipo de cliente que usa a API. Por exemplo, o gateway de API pode permitir que todos os clientes leiam recursos, mas limita gravações para clientes com credenciais de autenticação adequadas;
  • Otimiza a coordenação e reduz o número de solicitações. Um gateway de API atua como controlador para agregar informações solicitadas do cliente. Com um cliente móvel, essa agregação é importante porque cada solicitação de roundtrip na Internet é cara em termos de tempo e energia da bateria. Essa coordenação também significa que o cliente só precisa fazer uma solicitação.

Na maioria dos casos, esses benefícios compensam a complexidade da necessidade de implementar e instalar outro serviço. Eles também compensam o possível problema de um gateway se tornar um gargalho na comunicação, já que todas as APIs são roteadas por meio dele.

Em nosso aplicativo de amostra, usaremos a UI como o gateway de API. A UI possui a responsabilidade dupla de renderizar o app da web e atuar como o controlador frontal (gateway de API) do aplicativo.

Isso funciona bem para um app de amostra pequeno, mas não deve ser usado em um aplicativo de produto real. É comum desejar desenvolver vários clientes para um determinado aplicativo. Um exemplo seria um cliente CLI, um Web client e um cliente móvel. Acoplando o gateway de API com uma (única) interface com o usuário, não podemos implementar clientes adicionais facilmente.

Usando apps CF para microsserviços

Nesteartigo, os microsserviços cat e cart são implementados como aplicativos Cloud Foundry. O cliente UI também é implementado como um aplicativo Cloud Foundry. Uma questão fundamental com todos os aplicativos baseados em microsserviço é como manipular o registro de serviço e a descoberta de serviço. Aqui, usaremos o arquivo manifest de Cloud Foundry para declarar cada microsserviço e seu terminal de API associado.

Essa abordagem tem a vantagem de ser simples para implementação e não exigir um registro de serviço separado. Também permite que o código-fonte do aplicativo seja independente de seu empacotamento. É possível implementar o mesmo código-fonte cat como um microsserviço de app CF e em um ambiente de microsserviço baseado em contêiner IBM. O contexto é transmitido usando variáveis de ambiente sem necessidade de acesso a um registro de serviço.

A desvantagem dessa abordagem é que ela é completamente estática; se qualquer terminal de microsserviço mudar, será necessário fazer uma implementação totalmente nova.

Vamos implementar nosso aplicativo de compras no Bluemix. Plataformas em nuvem como IBM Bluemix fornecem os recursos essenciais de alta disponibilidade e escala horizontal e vertical.

Etapa 1. Crie a estrutura de aplicativo

  • Crie um diretório-raiz para seu aplicativo (“shop”);
  • Crie subdiretórios para cada microsserviço (“cat”, “cart”) e a UI (“ui”);

  • Vá para o Bluemix e crie aplicativos para cat, cart e ui.

Etapa 2. Crie o arquivo manifest

Um único arquivo manifest implementa todos os microsserviços (usando o comando cf push ). O arquivo manifest transmite os terminais de API como variáveis de ambiente para cada microsserviço.

O arquivo manifest.yml de CF controla a implementação dos microsserviços e permite transmitir as variáveis de ambiente adicionais conforme necessário.

---
disk_quota: 1024M
domain: mybluemix.net
instances: 1
memory: 128M
env:
  MONGODB_URI: mongodb://<user>:<pass>@ds061112.mongolab.com:61112/IbmCloud_381vomtk_ppokkvq4
  CART_ENTRYPOINT: http://davet-cart.mybluemix.net
  CAT_ENTRYPOINT: http://davet-cat.mybluemix.net
applications:
- name: davet-cat
  path: ./cat/src/
- name: davet-cart
  path: ./cart/src
- name: davet-shop
  path: ./ui/src

O arquivo manifest declara três aplicativos: davet-cat, davet-cart e davet-shop. A interface com o usuário é o aplicativo davet-shop, e o manifest declara as URLs de ponto de entrada para cat e cart nas variáveis de ambiente CAT_ENTRYPOINT e na CART_ENTRYPOINT, respectivamente.

Usamos o banco de dados MongoDB para armazenar nossas informações de produto. Podemos conectar o servidor MongoLab aos apps CF, mas, para simplificar, transmitiremos a sequência de conexão de Mongo como uma variável de ambiente.

Etapa 3. Inclua arquivos de implementação

Além de um arquivo manifest central, cada diretório de código-fonte de microsserviço inclui o seguinte:

  • Procfile: especifica o comando a ser executado quando o app CF inicia;
  • requirements.txt: requisitos da biblioteca Python;
  • runtime.txt: instrução CF de qual versão do tempo de execução Python usar.

Cada aplicativo Cloud Foundry em nossa amostra é gravado no Python usando a estrutura Flask. O arquivo requirements.txt especifica a versão aceitável de Flask e os componentes requeridos:

Flask == 0.10.0
pymongo >= 3.0

(pymongo é o driver de banco de dados MongoDB para Python que usamos).

Etapa 4. Implemente os microsserviços

A implementação dos aplicativos cat, cart e UI individuais como aplicativos Flask simples não é abrangida neste artigo. Consulte o código-fonte para obter detalhes.

O arquivo manifest declara os terminais para cada microsserviço. O Bluemix transmite as informações de ambiente em todos os apps CF declarados no manifest e contaremos com isso para iniciar nosso aplicativo. Por exemplo, o aplicativo UI localiza o microsserviço cart com o seguinte fragmento de código:

CART_ENTRYPOINT = os.environ['CART_ENTRYPOINT'] if 'CART_ENTRYPOINT' in os.environ else ''

Em algumas abordagens do gateway de API, todo tráfego é roteado para o gateway de API. Isso inclui a comunicação entre microsserviços. Nesse caso, o gateway de API está atuando como um proxy reverso para o aplicativo, tanto interna, quanto externamente.

Aqui, escolhemos expor os terminais de API diretos para todos os microsserviços. Essa escolha tem a vantagem de reduzir o tráfego de rede entre microsserviços.

Conclusão

O uso do arquivo manifest de app CF para registro e descoberta de serviço é uma abordagem simples da criação de um aplicativo baseado em microsserviço. A desvantagem é a natureza relativamente estática do registro de serviço. Fazer um cf push com um novo arquivo manifest pode não escalar um aplicativo em nuvem em cargas pesadas. Além disso, usando a abordagem de registro do arquivo manifest, não é possível suportar a implementação Red/Black e outras melhores práticas de DevOps.

É possível usar contêineres IBM para solucionar esses problemas. Para o custo de uma complexidade maior com o registro e a descoberta de serviço, é possível suportar a escala automática de serviços e a modificação dinâmica dos serviços enquanto minimiza o tempo.

O próximo artigo nesta série demonstra como implementar uma arquitetura de microsserviço usando contêineres IBM.