Este guia de referência é o primeiro de uma série de quatro partes sobre como projetar, criar e implantar microsserviços. Esta série descreve os vários elementos de uma arquitetura de microsserviços. A série inclui informações sobre os benefícios e as desvantagens do padrão de arquitetura de microsserviços e como aplicá-lo.
- Introdução aos microsserviços (este documento)
- Refatorar um monolítico em microsserviços
- Comunicação entre serviços em uma configuração de microsserviços
- Rastreamento distribuído em um aplicativo de microsserviços
Esta série é destinada a desenvolvedores e arquitetos de aplicativos que projetam e implementam a migração para refatorar um aplicativo monolítico em um aplicativo de microsserviços.
Aplicativos monolíticos
Um aplicativo monolítico é um aplicativo de software de nível único em que módulos diferentes são combinados em um único programa. Por exemplo, se você estiver criando um aplicativo de comércio eletrônico, o aplicativo deverá ter uma arquitetura modular alinhada com os princípios de programação orientada a objetos (OOP, na sigla em inglês). O diagrama a seguir mostra um exemplo de configuração de aplicativo de comércio eletrônico, em que o aplicativo consiste em vários módulos. Em um aplicativo monolítico, os módulos são definidos usando uma combinação de construções da linguagem de programação (como pacotes Java) e artefatos de compilação (como arquivos JAR do Java).
Figura 1. Diagrama de um aplicativo de comércio eletrônico monolítico com vários módulos usando uma combinação de construções da linguagem de programação.
Na figura 1, módulos diferentes no aplicativo de comércio eletrônico correspondem à lógica de negócios para pagamento, entrega e gerenciamento de pedidos. Todos esses módulos são empacotados e implantados como um único executável lógico. O formato real depende da linguagem e do framework do aplicativo. Por exemplo, muitos aplicativos Java são empacotados como arquivos JAR e implantados em servidores de aplicativos como o Tomcat ou o Jetty. Da mesma forma, um aplicativo Rails ou Node.js é empacotado como uma hierarquia de diretórios.
Benefícios do monolítico
A arquitetura monolítica é uma solução convencional para a criação de aplicativos. Veja a seguir algumas vantagens da adoção de um design monolítico para seu aplicativo:
- É possível implementar testes completos de um aplicativo monolítico usando ferramentas como o Selenium.
- Para implantar um aplicativo monolítico, basta copiá-lo para um servidor.
- Todos os módulos em um aplicativo monolítico compartilham memória, espaço e recursos. Assim, é possível usar uma única solução para lidar com questões de corte cruzado, como geração de registros, armazenamento em cache e segurança.
- A abordagem monolítica pode fornecer vantagens de desempenho, porque os módulos podem chamar uns aos outros diretamente. Por outro lado, os microsserviços normalmente exigem uma chamada de rede para se comunicar entre si.
Desafios do monolítico
Monolíticos complexos geralmente se tornam progressivamente mais difíceis de criar, depurar e raciocinar. Em algum momento, os problemas valem mais que os benefícios.
- Os aplicativos geralmente crescem com o tempo. Pode se tornar complicado implementar alterações em um aplicativo grande e complexo que tem módulos estreitamente acoplados. Como qualquer alteração de código afeta todo o sistema, você precisa coordenar completamente as alterações. A coordenação de alterações torna o processo geral de desenvolvimento e teste muito mais longo em comparação com aplicativos de microsserviço.
- Pode ser complicado conseguir integração e implantação contínuas (CI/CD) com um grande monolítico. Essa complexidade ocorre porque é necessário reimplantar todo o aplicativo para atualizar qualquer parte dele. Além disso, é provável que você precise fazer testes manuais abrangentes de todo o aplicativo para verificar regressões.
- Os aplicativos monolíticos podem ser difíceis de escalonar quando diferentes módulos têm requisitos de recursos conflitantes. Por exemplo, um módulo pode implementar uma lógica de processamento de imagem com uso intensivo de CPU. Outro módulo pode ser um banco de dados na memória. Como esses módulos são implantados juntos, você precisa comprometer a escolha do hardware.
- Como todos os módulos são executados no mesmo processo, um bug em qualquer módulo, como um vazamento de memória, pode derrubar todo o sistema.
- Os aplicativos monolíticos aumentam a complexidade quando você quer adotar novos frameworks e linguagens. Por exemplo, é caro (em tempo e dinheiro) reescrever um aplicativo inteiro para usar uma nova estrutura, mesmo que essa estrutura seja consideravelmente melhor.
Aplicativos baseados em microsserviços
Um microsserviço geralmente implementa um conjunto de recursos ou funcionalidades distintas. Cada microsserviço é um miniaplicativo que tem a própria arquitetura e lógica de negócios. Por exemplo, alguns microsserviços expõem uma API consumida por outros microsserviços ou pelos clientes do aplicativo, como integrações de terceiros com gateways de pagamento e logística.
A Figura 1 mostra um aplicativo de comércio eletrônico monolítico com vários módulos. No diagrama a seguir, mostramos uma possível decomposição do aplicativo de comércio eletrônico em microsserviços:
Figura 2. Diagrama de um aplicativo de comércio eletrônico com áreas funcionais implementadas por microsserviços.
Na figura 2, um microserve dedicado implementa cada área funcional do aplicativo de comércio eletrônico. Cada serviço de back-end pode expor uma API, e os serviços consomem APIs fornecidas por outros serviços. Por exemplo, para renderizar páginas da Web, os serviços da IU invocam o serviço de finalização da compra e outros serviços. Os serviços também podem usar a comunicação assíncrona baseada em mensagens. Para mais informações sobre como os serviços se comunicam, consulte o terceiro documento desta série, Comunicação entre serviços em uma configuração de microsserviços.
O padrão de arquitetura de microsserviços altera significativamente a relação entre o aplicativo e o banco de dados. Em vez de compartilhar um único banco de dados com outros serviços, recomendamos que cada serviço tenha o próprio banco de dados que melhor se adapte aos requisitos. Quando você tem um banco de dados para cada serviço, garante um acoplamento flexível entre os serviços, porque todas as solicitações de dados passam pela API e não pelo banco de dados compartilhado. O diagrama a seguir mostra um padrão de arquitetura de microsserviços em que cada serviço tem o próprio banco de dados:
Figura 3. Cada serviço em uma arquitetura de microsserviço tem seu próprio banco de dados.
Na figura 3, o serviço de pedido no aplicativo de comércio eletrônico funciona bem usando um banco de dados orientado a documentos que tem recursos de pesquisa em tempo real. Os serviços de pagamento e entrega dependem das garantias sólidas de atomicidade, consistência, isolamento, durabilidade (ACID) de um banco de dados relacional.
Benefícios dos microsserviços
O padrão de arquitetura de microsserviços aborda o problema da complexidade descrito na seção anterior Desafios de aplicativos monolíticos. Uma arquitetura de microsserviços oferece os seguintes benefícios:
- A funcionalidade total não foi alterada, mas você usa microsserviços para separar o aplicativo em blocos ou serviços gerenciáveis. Cada serviço tem um limite bem definido na forma de uma API RPC ou orientada por mensagens. Portanto, os serviços individuais podem ser mais rápidos de desenvolver, mais fáceis de entender e manter.
- As equipes autônomas podem desenvolver serviços individuais de forma independente. É possível organizar microsserviços em torno dos limites de negócios, e não os recursos técnicos de um produto. Você organiza suas equipes para uma responsabilidade única e independente para todo o ciclo de vida de seu software atribuído, desde o desenvolvimento até o teste, a implantação e a manutenção e monitoramento.
- O processo de desenvolvimento de microsserviços independente também permite que os desenvolvedores escrevam cada microsserviço em uma linguagem de programação diferente, criando um aplicativo poliglota. Ao usar a linguagem mais eficaz para cada microsserviço, você pode desenvolver um aplicativo mais rapidamente e otimizá-lo para reduzir a complexidade do código e aumentar o desempenho e a funcionalidade.
- Ao desacoplar recursos de um monolítico, é possível fazer com que as equipes independentes liberem o microsserviço de modo independente. Ciclos de lançamento independentes podem ajudar a melhorar a velocidade e o tempo de produção das suas equipes no mercado.
- A arquitetura de microsserviços também permite escalonar cada serviço de maneira independente. É possível implantar o número de instâncias de cada serviço que atendam às restrições de capacidade e disponibilidade. Também é possível usar o hardware que melhor atende aos requisitos de recursos de um serviço. Ao escalonar serviços de maneira independente, você ajuda a aumentar a disponibilidade e a confiabilidade de todo o sistema.
Veja a seguir algumas instâncias específicas em que é interessante migrar de um monolítico para uma arquitetura de microsserviço:
- Implementar melhorias na escalonabilidade, no gerenciamento, na agilidade ou na velocidade da entrega.
- Reescrita incremental de um grande aplicativo legado em uma pilha moderna de linguagem e tecnologia para atender às novas demandas de negócios
- Extrair aplicativos de negócios multicorreção ou serviços de corte cruzado para que você possa reutilizá-los em vários canais. Exemplos de serviços que você pode querer reutilizar incluem serviços de pagamento, serviços de login, serviços de criptografia, serviços de pesquisa de voos, serviços de perfil de cliente e serviços de notificação.
- Adotar uma linguagem ou framework personalizado para uma funcionalidade específica de um monolítico.
Desafios de microsserviços
Os microsserviços têm alguns desafios em comparação com os monolíticos, incluindo:
- Um grande desafio dos microsserviços é a complexidade causada porque o aplicativo é um sistema distribuído. Os desenvolvedores precisam escolher e implementar um mecanismo de comunicação entre serviços. Os serviços também precisam lidar com falhas parciais e indisponibilidade dos serviços upstream.
Outro desafio com microsserviços é que você precisa gerenciar transações em diferentes microsserviços (também chamados de transação distribuída). As operações de negócios que atualizam várias entidades de negócios são bastante comuns e geralmente são aplicadas de maneira atômica, em que todas as operações são aplicadas ou tudo falha. Ao unir várias operações em uma única transação do banco de dados, você garante a atomicidade.
Em um aplicativo baseado em microsserviços, as operações de negócios podem estar espalhadas por microsserviços diferentes. Portanto, você precisa atualizar vários bancos de dados de propriedade de serviços diferentes. Se houver uma falha, não é trivial rastrear a falha ou o sucesso de chamadas para os diferentes microsserviços e o estado de reversão. O pior cenário pode resultar em dados inconsistentes entre os serviços quando a reversão do estado devido a falhas não aconteceu corretamente. Para informações sobre as várias metodologias para configurar transações distribuídas entre serviços, consulte o terceiro documento desta série, Comunicação entre serviços em uma configuração de microsserviços.
O teste abrangente de aplicativos baseados em microsserviços é mais complexo do que testar um aplicativo monolítico. Por exemplo, para testar a funcionalidade de processamento de um pedido em um serviço de comércio eletrônico monolítico, selecione os itens, adicione-os a um carrinho e faça check-out. Para testar o mesmo fluxo em uma arquitetura baseada em microsserviços, vários serviços, como front-end, pedido e pagamento, chamam uns aos outros para concluir a execução do teste.
A implantação de um aplicativo baseado em microsserviços é mais complexa do que a implantação de um aplicativo monolítico. Um aplicativo de microsserviço geralmente consiste em muitos serviços, cada um com várias instâncias de ambiente de execução. Você também precisa implementar um mecanismo de descoberta de serviço que permita que um serviço descubra os locais de outros serviços com os quais ele precisa se comunicar.
Uma arquitetura de microsserviços adiciona sobrecarga de operações porque há mais serviços para monitorar e alertar. A arquitetura de microsserviços também tem mais pontos de falha devido ao aumento dos pontos de comunicação de serviço a serviço. Um aplicativo monolítico pode ser implantado em um pequeno cluster de servidor de aplicativos. Um aplicativo baseado em microsserviços pode ter dezenas de serviços separados para criar, testar, implantar e executar, potencialmente em várias linguagens e ambientes. Todos esses serviços precisam ser agrupados para failover e resiliência. A produção de um aplicativo de microsserviços requer infraestrutura de operações e monitoramento de alta qualidade.
A divisão de serviços em uma arquitetura de microsserviço permite que o aplicativo execute mais funções ao mesmo tempo. No entanto, como os módulos são executados como serviços isolados, a latência é introduzida no tempo de resposta devido a chamadas de rede entre serviços.
Nem todos os aplicativos são grandes o suficiente para serem divididos em microsserviços. Além disso, alguns aplicativos exigem uma forte integração entre componentes. Por exemplo, aplicativos que precisam processar fluxos rápidos de dados em tempo real. Qualquer camada extra de comunicação entre serviços pode retardar o processamento em tempo real. Pensar na comunicação entre serviços com antecedência pode trazer insights úteis para marcar claramente os limites dos serviços.
Ao decidir se a arquitetura de microsserviço é melhor para seu aplicativo, considere os seguintes pontos:
- As práticas recomendadas para microserviços exigem bancos de dados por serviço. Ao fazer a modelagem de dados para seu aplicativo, observe se os bancos de dados por serviço são adequados ao seu aplicativo.
- Ao implementar uma arquitetura de microsserviço, você precisa instrumentar e monitorar o ambiente para que possa identificar gargalos, detectar e evitar falhas e oferecer suporte a diagnósticos.
- Em uma arquitetura de microsserviço, cada serviço tem controles de acesso separados. Para garantir a segurança, você precisa proteger o acesso a cada serviço, tanto no ambiente quanto em aplicativos externos que consomem as APIs dele.
- A comunicação síncrona entre serviços normalmente reduz a disponibilidade de um aplicativo. Por exemplo, se o serviço de pedido em um aplicativo de comércio eletrônico invocar de maneira síncrona outros serviços upstream e se esses serviços estiverem indisponíveis, ele não poderá criar um pedido. Portanto, recomendamos que você implemente a comunicação assíncrona e baseada em mensagens.
Quando migrar um aplicativo monolítico para microsserviços
Se você já está executando um monolítico, a adoção de microsserviços é um custo de investimento significativo para sua equipe. Equipes diferentes implementam os princípios dos microsserviços de maneiras distintas. Cada equipe de engenharia tem resultados únicos para o tamanho dos microsserviços ou quantos microsserviços eles precisam.
Para determinar se os microsserviços são a melhor abordagem para seu aplicativo, primeiro identifique os principais objetivos de negócios ou pontos problemáticos que você quer abordar. Talvez haja maneiras mais simples de alcançar suas metas ou resolver os problemas identificados. Por exemplo, se você quiser escalonar o aplicativo mais rapidamente, verá que o escalonamento automático é uma solução mais eficiente. Se você encontrar bugs na produção, comece implementando testes de unidade e integração contínua (CI).
Se você acredita que uma abordagem de microsserviço é a melhor maneira de atingir suas metas, comece extraindo um serviço do aplicativo monolítico e depois desenvolva, teste e implante-o na produção. Para mais informações, consulte o próximo documento desta série, Refatorar um aplicativo monolítico em microsserviços. Depois de extrair um serviço e executá-lo na produção, inicie a extração do próximo serviço e continue aprendendo com cada ciclo.
O padrão de arquitetura de microsserviço decompõe um sistema em um conjunto de serviços implantáveis de maneira independente. Ao desenvolver um aplicativo monolítico, é necessário coordenar grandes equipes, o que pode causar lentidão no desenvolvimento de software. Ao implementar uma arquitetura de microsserviços, você permite que equipes pequenas e autônomas trabalhem em paralelo, o que pode acelerar seu desenvolvimento.
No próximo documento desta série, Refatorar um aplicativo monolítico em microsserviços, você vai aprender várias estratégias para refatorar um aplicativo monolítico em microsserviços.
A seguir
- Leia o próximo documento desta série para saber mais sobre as estratégias de refatoração de aplicativos para decompor microsserviços.
- Leia o terceiro documento desta série para saber mais sobre a comunicação entre serviços de uma configuração de microsserviços.
- Leia o quarto documento final desta série para saber mais sobre o rastreamento distribuído de solicitações entre microsserviços.