Por que usar uma abordagem de microsserviços para criar aplicativos

Para os desenvolvedores de software, a fatoração de um aplicativo em partes componentes não é novidade. Normalmente, uma abordagem hierárquica é usada, com um armazenamento back-end, lógica de negócios de camada intermediária e uma interface do usuário front-end. O que mudou nos últimos anos é que os desenvolvedores estão criando aplicativos distribuídos para a nuvem.

Aqui estão algumas necessidades de negócios em mudança:

  • Um serviço construído e operado em escala para alcançar clientes em novas regiões geográficas.
  • Entrega mais rápida de recursos e capacidades para responder às demandas dos clientes de forma ágil.
  • Melhor utilização de recursos para reduzir custos.

Essas necessidades de negócios estão afetando a forma como criamos aplicativos.

Para obter mais informações sobre a abordagem do Azure aos microsserviços, consulte Microsserviços: uma revolução de aplicativos alimentada pela nuvem.

Abordagem de design monolítico versus microsserviços

As aplicações evoluem ao longo do tempo. As aplicações bem-sucedidas evoluem por serem úteis para as pessoas. Os aplicativos malsucedidos não evoluem e acabam sendo preteridos. Aqui está a pergunta: quanto você sabe sobre seus requisitos hoje e quais serão no futuro? Por exemplo, digamos que você esteja criando um aplicativo de relatórios para um departamento da sua empresa. Você tem certeza de que o aplicativo se aplica apenas no âmbito da sua empresa e que os relatórios não serão mantidos por muito tempo. Sua abordagem será diferente da, digamos, criação de um serviço que forneça conteúdo de vídeo para dezenas de milhões de clientes.

Às vezes, obter algo fora da porta como uma prova de conceito é o fator impulsionador. Você sabe que o aplicativo pode ser redesenhado mais tarde. De pouco adianta fazer engenharia excessiva de algo que nunca é usado. Por outro lado, quando as empresas constroem para a nuvem, a expectativa é de crescimento e uso. O crescimento e a escala são imprevisíveis. Queremos prototipar rapidamente, ao mesmo tempo em que sabemos que estamos em um caminho que pode lidar com o sucesso futuro. Esta é a abordagem lean startup: construir, medir, aprender e iterar.

Durante a era cliente/servidor, tendemos a nos concentrar na criação de aplicativos hierárquicos usando tecnologias específicas em cada camada. O termo aplicação monolítica surgiu para descrever essas abordagens. As interfaces tendiam a ser entre as camadas, e um design mais firmemente acoplado era usado entre os componentes dentro de cada camada. Os desenvolvedores projetaram e fatoraram classes que foram compiladas em bibliotecas e vinculadas em alguns arquivos executáveis e DLLs.

Há benefícios em uma abordagem de design monolítico. Aplicativos monolíticos geralmente são mais simples de projetar, e as chamadas entre componentes são mais rápidas porque essas chamadas geralmente são sobre comunicação entre processos (IPC). Além disso, todos testam um único produto, o que tende a ser um uso mais eficiente dos recursos humanos. A desvantagem é que há um acoplamento apertado entre camadas hierárquicas e você não pode dimensionar componentes individuais. Se você precisar fazer correções ou atualizações, terá que esperar que outros terminem seus testes. É mais difícil ser ágil.

Os microsserviços abordam essas desvantagens e se alinham mais estreitamente com os requisitos de negócios anteriores. Mas também têm benefícios e responsabilidades. Os benefícios dos microsserviços são que cada um deles normalmente encapsula funcionalidades de negócios mais simples, que podem ser dimensionadas ou ampliadas, testadas, implantadas e gerenciadas de forma independente. Um benefício importante de uma abordagem de microsserviços é que as equipes são orientadas mais por cenários de negócios do que pela tecnologia. As equipas mais pequenas desenvolvem um microsserviço com base num cenário de cliente e utilizam todas as tecnologias que pretendam utilizar.

Em outras palavras, a organização não precisa padronizar a tecnologia para manter aplicativos de microsserviços. Equipes individuais que possuem serviços podem fazer o que faz sentido para elas com base na experiência da equipe ou no que é mais apropriado para resolver o problema. Na prática, é preferível um conjunto de tecnologias recomendadas, como um repositório NoSQL específico ou uma estrutura de aplicação web.

A desvantagem dos microsserviços é que você precisa gerenciar entidades mais separadas e lidar com implantações e controle de versão mais complexos. O tráfego de rede entre os microsserviços aumenta, assim como as latências de rede correspondentes. Muitos serviços granulares e tagarelas podem causar um pesadelo de desempenho. Sem ferramentas para ajudá-lo a visualizar essas dependências, é difícil ver todo o sistema.

Os padrões fazem com que a abordagem de microsserviços funcione, especificando como se comunicar e tolerando apenas as coisas que você precisa de um serviço, em vez de contratos rígidos. É importante definir esses contratos antecipadamente no projeto, porque os serviços são atualizados independentemente uns dos outros. Outra descrição cunhada para projetar com uma abordagem de microsserviços é "arquitetura orientada a serviços (SOA) refinada".

Em sua forma mais simples, a abordagem de design de microsserviços é sobre uma federação dissociada de serviços, com mudanças independentes para cada um e padrões acordados para comunicação.

À medida que mais aplicativos em nuvem são produzidos, as pessoas descobriram que essa decomposição do aplicativo geral em serviços independentes e focados em cenários é uma melhor abordagem de longo prazo.

Comparação entre abordagens de desenvolvimento de aplicativos

Desenvolvimento de aplicativos da plataforma Service Fabric

  1. Um aplicativo monolítico contém funcionalidade específica do domínio e normalmente é dividido em camadas funcionais, como Web, negócios e dados.

  2. Você dimensiona um aplicativo monolítico clonando-o em vários servidores/máquinas virtuais/contêineres.

  3. Um aplicativo de microsserviço separa a funcionalidade em serviços menores separados.

  4. A abordagem de microsserviços é dimensionada implantando cada serviço de forma independente, criando instâncias desses serviços em servidores/máquinas virtuais/contêineres.

Projetar com uma abordagem de microsserviços não é apropriado para todos os projetos, mas se alinha mais estreitamente com os objetivos de negócios descritos anteriormente. Começar com uma abordagem monolítica pode fazer sentido se você souber que terá a oportunidade de retrabalhar o código mais tarde em um design de microsserviços. Mais comumente, você começa com uma aplicação monolítica e lentamente a divide em etapas, começando com as áreas funcionais que precisam ser mais escaláveis ou ágeis.

Quando você usa uma abordagem de microsserviços, compõe seu aplicativo de muitos serviços pequenos. Esses serviços são executados em contêineres que são implantados em um cluster de máquinas. Equipes menores desenvolvem um serviço que se concentra em um cenário e testam, versão, implantam e dimensionam cada serviço de forma independente para que todo o aplicativo possa evoluir.

O que é um microsserviço?

Existem diferentes definições de microsserviços. Mas a maioria dessas características dos microsserviços são amplamente aceitas:

  • Encapsular um cliente ou cenário de negócios. Que problema está a resolver?
  • Desenvolvido por uma pequena equipa de engenharia.
  • Escrito em qualquer linguagem de programação, usando qualquer framework.
  • Consistem em código e, opcionalmente, estado, ambos são versionados, implantados e dimensionados de forma independente.
  • Interaja com outros microsserviços através de interfaces e protocolos bem definidos.
  • Ter nomes exclusivos (URLs) que são usados para resolver sua localização.
  • Mantenha-se consistente e disponível na presença de falhas.

Resumindo:

Os aplicativos de microsserviço são compostos por serviços pequenos, com versões independentes e escaláveis, focados no cliente, que se comunicam entre si por meio de protocolos padrão com interfaces bem definidas.

Escrito em qualquer linguagem de programação, usando qualquer framework

Como desenvolvedores, queremos ser livres para escolher uma linguagem ou estrutura, dependendo de nossas habilidades e das necessidades do serviço que estamos criando. Para alguns serviços, você pode valorizar os benefícios de desempenho do C++ acima de qualquer outra coisa. Para outros, a facilidade de desenvolvimento gerenciado que você obtém do C# ou Java pode ser mais importante. Em alguns casos, talvez seja necessário usar uma biblioteca de parceiros específica, uma tecnologia de armazenamento de dados ou um método para expor o serviço aos clientes.

Depois de escolher uma tecnologia, você precisa considerar o gerenciamento operacional ou do ciclo de vida e o dimensionamento do serviço.

Permite que o código e o estado sejam versionados, implantados e dimensionados de forma independente

Não importa como você escreve seus microsserviços, o código e, opcionalmente, o estado, devem ser implantados, atualizados e dimensionados de forma independente. Este problema é difícil de resolver porque se resume à sua escolha de tecnologias. Para dimensionamento, entender como particionar (ou fragmentar) o código e o estado é um desafio. Quando o código e o estado usam tecnologias diferentes, o que é comum atualmente, os scripts de implantação do seu microsserviço precisam ser capazes de dimensionar ambos. Essa separação também tem a ver com agilidade e flexibilidade, para que você possa atualizar alguns dos microsserviços sem ter que atualizar todos eles de uma só vez.

Voltemos à nossa comparação das abordagens monolítica e de microsserviços por um momento. Este diagrama mostra as diferenças nas abordagens para armazenar o estado:

Armazenamento de estado para as duas abordagens

Armazenamento de estado da plataforma Service Fabric

A abordagem monolítica, à esquerda, tem um único banco de dados e camadas de tecnologias específicas.

A abordagem de microsserviços, à direita, tem um gráfico de microsserviços interconectados, onde o estado é normalmente definido como escopo para o microsserviço e várias tecnologias são usadas.

Em uma abordagem monolítica, o aplicativo normalmente usa um único banco de dados. A vantagem de usar um banco de dados é que ele está em um único local, o que facilita a implantação. Cada componente pode ter uma única tabela para armazenar seu estado. As equipes precisam separar rigorosamente o estado, o que é um desafio. Inevitavelmente, alguém ficará tentado a adicionar uma coluna a uma tabela de cliente existente, fazer uma junção entre tabelas e criar dependências na camada de armazenamento. Depois que isso acontece, você não pode dimensionar componentes individuais.

Na abordagem de microsserviços, cada serviço gerencia e armazena seu próprio estado. Cada serviço é responsável por dimensionar o código e o estado juntos para atender às demandas do serviço. Uma desvantagem é que, quando você precisa criar exibições ou consultas dos dados do seu aplicativo, precisa consultar vários repositórios de estado. Esse problema normalmente é resolvido por um microsserviço separado que cria uma exibição em uma coleção de microsserviços. Se você precisar executar várias consultas improvisadas nos dados, considere gravar os dados de cada microsserviço em um serviço de armazenamento de dados para análise offline.

Os microsserviços são versionados. É possível que diferentes versões de um microsserviço sejam executadas lado a lado. Uma versão mais recente de um microsserviço pode falhar durante uma atualização e precisa ser revertida para uma versão anterior. O controle de versão também é útil para testes A/B, em que diferentes usuários experimentam diferentes versões do serviço. Por exemplo, é comum atualizar um microsserviço para um conjunto específico de clientes para testar novas funcionalidades antes de implementá-las mais amplamente.

Interage com outros microsserviços através de interfaces e protocolos bem definidos

Nos últimos 10 anos, foram publicadas extensas informações descrevendo padrões de comunicação em arquiteturas orientadas a serviços. Geralmente, a comunicação de serviço usa uma abordagem REST com protocolos HTTP e TCP e XML ou JSON como o formato de serialização. Do ponto de vista da interface, trata-se de adotar uma abordagem de web design. Mas nada deve impedi-lo de usar protocolos binários ou seus próprios formatos de dados. Apenas esteja ciente de que as pessoas terão mais dificuldade em usar seus microsserviços se esses protocolos e formatos não estiverem disponíveis abertamente.

Tem um nome exclusivo (URL) usado para resolver sua localização

Seu microsserviço precisa ser endereçável onde quer que esteja em execução. Se você está pensando em máquinas e qual delas está executando um determinado microsserviço, as coisas podem ficar ruins rapidamente.

Da mesma forma que o DNS resolve uma URL específica para uma máquina específica, seu microsserviço precisa de um nome exclusivo para que sua localização atual seja detetável. Os microsserviços precisam de nomes endereçáveis que sejam independentes da infraestrutura em que estão sendo executados. Isso implica que há uma interação entre como seu serviço é implantado e como ele é descoberto, porque precisa haver um registro de serviço. Quando uma máquina falha, o serviço de registro precisa informar para onde o serviço foi movido.

Permanece consistente e disponível na presença de falhas

Lidar com falhas inesperadas é um dos problemas mais difíceis de resolver, especialmente em um sistema distribuído. Grande parte do código que escrevemos como desenvolvedores é para lidar com exceções. Durante os testes, também gastamos mais tempo no tratamento de exceções. O processo está mais envolvido do que escrever código para lidar com falhas. O que acontece quando a máquina na qual o microsserviço está sendo executado falha? Você precisa detetar a falha, que é um problema difícil por si só. Mas você também precisa reiniciar seu microsserviço.

Para disponibilidade, um microsserviço precisa ser resiliente a falhas e capaz de reiniciar em outra máquina. Além desses requisitos de resiliência, os dados não devem ser perdidos e precisam permanecer consistentes.

A resiliência é difícil de alcançar quando ocorrem falhas durante uma atualização de aplicativo. O microsserviço, trabalhando com o sistema de implantação, não precisa se recuperar. Ele precisa determinar se pode continuar a avançar para a versão mais recente ou reverter para uma versão anterior para manter um estado consistente. Você precisa considerar algumas perguntas, como se há máquinas suficientes disponíveis para continuar avançando e como recuperar versões anteriores do microsserviço. Para tomar essas decisões, você precisa do microsserviço para emitir informações de saúde.

Relatórios de integridade e diagnósticos

Pode parecer óbvio, e muitas vezes é negligenciado, mas um microsserviço precisa relatar sua saúde e diagnósticos. Caso contrário, você tem pouca visão sobre sua integridade do ponto de vista das operações. Correlacionar eventos de diagnóstico em um conjunto de serviços independentes e lidar com distorções de relógio da máquina para entender a ordem do evento é um desafio. Da mesma forma que você interage com um microsserviço sobre protocolos e formatos de dados acordados, você precisa padronizar como registrar eventos de integridade e diagnóstico que, em última análise, acabarão em um armazenamento de eventos para consulta e visualização. Com uma abordagem de microsserviços, diferentes equipes precisam concordar em um único formato de registro. Precisa haver uma abordagem consistente para exibir eventos de diagnóstico no aplicativo como um todo.

A saúde é diferente do diagnóstico. Saúde é sobre o microsserviço relatar seu estado atual para tomar as ações apropriadas. Um bom exemplo é trabalhar com mecanismos de atualização e implantação para manter a disponibilidade. Embora um serviço possa estar atualmente não íntegro devido a uma falha de processo ou reinicialização da máquina, o serviço ainda pode estar operacional. A última coisa que você precisa é piorar a situação iniciando uma atualização. A melhor abordagem é investigar primeiro ou dar tempo para que o microsserviço se recupere. Os eventos de saúde de um microsserviço ajudam-nos a tomar decisões informadas e, de facto, ajudam a criar serviços de autorrecuperação.

Orientação para projetar microsserviços no Azure

Visite o centro de arquitetura do Azure para obter orientações sobre como projetar e criar microsserviços no Azure.

Service Fabric como plataforma de microsserviços

O Azure Service Fabric surgiu quando a Microsoft fez a transição da entrega de produtos in a box, que normalmente eram monolíticos, para a entrega de serviços. A experiência de criar e operar grandes serviços, como o Banco de Dados SQL do Azure e o Azure Cosmos DB, moldou o Service Fabric. A plataforma evoluiu ao longo do tempo à medida que mais serviços a adotaram. O Service Fabric teve que ser executado não apenas no Azure, mas também em implantações autônomas do Windows Server.

O objetivo do Service Fabric é resolver os problemas difíceis de criar e executar um serviço e usar os recursos de infraestrutura de forma eficiente, para que as equipes possam resolver problemas de negócios usando uma abordagem de microsserviços.

O Service Fabric ajuda você a criar aplicativos que usam uma abordagem de microsserviços, fornecendo:

  • Uma plataforma que fornece serviços do sistema para implantar, atualizar, detetar e reiniciar serviços com falha, descobrir serviços, rotear mensagens, gerenciar o estado e monitorar a integridade.
  • A capacidade de implantar aplicativos em execução em contêineres ou como processos. O Service Fabric é um orquestrador de contêineres e processos.
  • APIs de programação produtivas para ajudá-lo a criar aplicativos como microsserviços: ASP.NET Core, Reliable Actors e Reliable Services. Por exemplo, você pode obter informações de integridade e diagnóstico, ou pode aproveitar a alta disponibilidade interna.

O Service Fabric é agnóstico sobre como você cria seu serviço e você pode usar qualquer tecnologia. Mas ele fornece APIs de programação internas que facilitam a criação de microsserviços.

Migrando aplicativos existentes para o Service Fabric

O Service Fabric permite reutilizar o código existente e modernizá-lo com novos microsserviços. Há cinco estágios para a modernização do aplicativo, e você pode iniciar e parar a qualquer momento. As etapas são:

  1. Comece com uma aplicação monolítica tradicional.
  2. Migrar. Use contêineres ou executáveis convidados para hospedar o código existente no Service Fabric.
  3. Modernizar. Adicione novos microsserviços juntamente com o código conteinerizado existente.
  4. Inove. Divida o aplicativo monolítico em microsserviços com base na necessidade.
  5. Transforme aplicativos em microsserviços. Transforme aplicativos monolíticos existentes ou crie novos aplicativos greenfield.

Migração para microsserviços

Lembre-se, você pode começar e parar em qualquer um desses estágios. Você não precisa avançar para a próxima fase.

Vejamos exemplos para cada uma dessas etapas.

Migrar
Por dois motivos, muitas empresas estão migrando aplicativos monolíticos existentes para contêineres:

  • Redução de custos, seja devido à consolidação e remoção de hardware existente ou devido à execução de aplicativos em maior densidade.
  • Um contrato de implantação consistente entre desenvolvimento e operações.

As reduções de custos são simples. Na Microsoft, muitos aplicativos existentes estão sendo conteinerizados, levando a milhões de dólares em economias. Uma implantação consistente é mais difícil de avaliar, mas igualmente importante. Isso significa que os desenvolvedores podem escolher as tecnologias que mais lhes convêm, mas as operações aceitarão apenas um único método para implantar e gerenciar os aplicativos. Ele alivia as operações de terem que lidar com a complexidade do suporte a diferentes tecnologias sem forçar os desenvolvedores a escolher apenas algumas. Essencialmente, cada aplicativo é colocado em contêineres em imagens de implantação autônomas.

Muitas organizações param por aqui. Eles já têm os benefícios dos contêineres, e o Service Fabric fornece a experiência completa de gerenciamento, incluindo implantação, atualizações, controle de versão, reversões e monitoramento de integridade.

Modernizar
A modernização é a adição de novos serviços ao lado do código conteinerizado existente. Se você vai escrever um novo código, é melhor dar pequenos passos no caminho dos microsserviços. Isso pode significar a adição de um novo ponto de extremidade da API REST ou uma nova lógica de negócios. Dessa forma, você inicia o processo de criação de novos microsserviços e pratica o desenvolvimento e a implantação dos mesmos.

Inovar
Uma abordagem de microsserviços acomoda as necessidades de negócios em constante mudança. Nesta etapa, você precisa decidir se deseja começar a dividir o aplicativo monolítico em serviços ou inovar. Um exemplo clássico aqui é quando um banco de dados que você está usando como uma fila de fluxo de trabalho se torna um gargalo de processamento. À medida que o número de solicitações de fluxo de trabalho aumenta, o trabalho precisa ser distribuído para escala. Pegue aquela parte específica do aplicativo que não está dimensionando, ou que precisa ser atualizada com mais frequência, e separe-a como um microsserviço e inove.

Transforme aplicativos em microsserviços
Nesta etapa, seu aplicativo é totalmente composto por (ou dividido em) microsserviços. Para chegar a este ponto, você fez a jornada dos microsserviços. Você pode começar aqui, mas para fazê-lo sem uma plataforma de microsserviços para ajudá-lo requer um investimento significativo.

Os microsserviços são adequados para a minha aplicação?

Talvez. Na Microsoft, à medida que mais equipes começaram a criar para a nuvem por motivos comerciais, muitas delas perceberam os benefícios de adotar uma abordagem semelhante a um microsserviço. O Bing, por exemplo, usa microsserviços há anos. Para outras equipes, a abordagem de microsserviços era nova. As equipas descobriram que havia problemas difíceis de resolver fora das suas principais áreas de força. É por isso que o Service Fabric ganhou força como a tecnologia para serviços de construção.

O objetivo do Service Fabric é reduzir as complexidades da criação de aplicativos de microsserviço para que você não precise passar por tantas reformulações dispendiosas. Comece pequeno, dimensione quando necessário, desvalorize serviços, adicione novos e evolua com o uso do cliente. Também sabemos que há muitos outros problemas ainda a serem resolvidos para tornar os microsserviços mais acessíveis para a maioria dos desenvolvedores. Containers e o modelo de programação de atores são exemplos de pequenos passos nessa direção. Temos certeza de que mais inovações surgirão para facilitar uma abordagem de microsserviços.

Próximos passos