Porquê utilizar uma abordagem de microsserviços para criar aplicações

Para os programadores de software, a fatoração de uma aplicação em partes de componentes não é novidade. Normalmente, é utilizada uma abordagem em camadas, com um arquivo de back-end, lógica de negócio de camada média e uma interface de utilizador (IU) de front-end. O que mudou ao longo dos últimos anos é que os programadores estão a criar aplicações distribuídas para a cloud.

Seguem-se algumas necessidades empresariais em mudança:

  • Um serviço criado e operado em escala para chegar aos clientes em novas regiões geográficas.
  • Entrega mais rápida de funcionalidades e capacidades para responder às exigências dos clientes de uma forma ágil.
  • Utilização de recursos melhorada para reduzir os custos.

Estas necessidades empresariais estão a afetar a forma como criamos aplicações.

Para obter mais informações sobre a abordagem do Azure aos microsserviços, veja Microsserviços: uma revolução de aplicações com tecnologia da cloud.

Abordagem de design monolítica vs. microsserviços

As aplicações evoluem ao longo do tempo. As aplicações bem-sucedidas evoluem ao serem úteis para as pessoas. As aplicações sem êxito não evoluem e acabam por ser preteridas. Eis a questão: o que sabe sobre os seus requisitos hoje e o que serão no futuro? Por exemplo, digamos que está a criar uma aplicação de relatórios para um departamento na sua empresa. Tem a certeza de que a aplicação se aplica apenas no âmbito da sua empresa e que os relatórios não serão mantidos por muito tempo. A sua abordagem será diferente da da criação de um serviço que fornece conteúdos de vídeo a dezenas de milhões de clientes.

Às vezes, tirar algo da porta como prova de conceito é o fator de condução. Sabe que a aplicação pode ser redesenhada mais tarde. Há pouco sentido na engenharia excessiva algo que nunca é usado. Por outro lado, quando as empresas criam para a cloud, a expectativa é o crescimento e a utilização. O crescimento e a escala são imprevisíveis. Queremos criar protótipos rapidamente, sabendo também que estamos num caminho que pode lidar com o sucesso futuro. Esta é a abordagem de arranque magro: criar, medir, aprender e iterar.

Durante a era cliente/servidor, tendemos a concentrar-nos na criação de aplicações em camadas através de tecnologias específicas em cada camada. O termo aplicação monolítica surgiu para descrever estas abordagens. As interfaces tendiam a estar entre as camadas e era utilizado um design mais fortemente conjugado entre componentes dentro de cada camada. Os programadores conceberam e consideraram classes compiladas em bibliotecas e ligadas em alguns ficheiros executáveis e DLLs.

Existem benefícios para uma abordagem de design monolítica. Muitas vezes, as aplicações monolíticas são mais simples de conceber e as chamadas entre componentes são mais rápidas porque estas chamadas são, muitas vezes, através da comunicação entre processos (IPC). Além disso, todos testam um único produto, que tende a ser uma utilização mais eficiente dos recursos humanos. A desvantagem é que existe um acoplamento apertado entre camadas em camadas e não pode dimensionar componentes individuais. Se precisar de fazer correções ou atualizações, terá de esperar que outras pessoas terminem os testes. É mais difícil ser ágil.

Os microsserviços abordam estas desvantagens e alinham-se mais estreitamente com os requisitos comerciais anteriores. Mas também têm benefícios e passivos. Os benefícios dos microsserviços são o facto de cada um encapsular normalmente funcionalidades empresariais mais simples, que pode aumentar ou reduzir horizontalmente, testar, implementar e gerir de forma independente. Um benefício importante de uma abordagem de microsserviços é que as equipas são mais orientadas por cenários empresariais 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.

Por outras palavras, a organização não precisa de uniformizar a tecnologia para manter aplicações de microsserviços. As equipas individuais que possuem serviços podem fazer o que faz sentido para elas com base na experiência da equipa ou no que é mais adequado para resolver o problema. Na prática, é preferível um conjunto de tecnologias recomendadas, como um arquivo NoSQL específico ou uma arquitetura de aplicações Web.

A desvantagem dos microsserviços é que tem de gerir entidades mais separadas e lidar com implementações e controlo de versões mais complexos. O tráfego de rede entre os microsserviços aumenta, assim como as latências de rede correspondentes. Muitos serviços chatty e granulares podem causar um pesadelo de desempenho. Sem ferramentas para o ajudar a ver estas dependências, é difícil ver todo o sistema.

As normas fazem com que a abordagem dos microsserviços funcione ao especificar como comunicar e tolerar apenas as coisas de que precisa de um serviço, em vez de contratos rígidos. É importante definir estes contratos antecipadamente na conceção, uma vez que os serviços são atualizados independentemente uns dos outros. Outra descrição para conceber com uma abordagem de microsserviços é "arquitetura detalhada orientada para serviços (SOA)."

Na sua forma mais simples, a abordagem de design de microsserviços tem a ver com uma federação desacoplada de serviços, com alterações independentes a cada um e normas acordadas para a comunicação.

À medida que são produzidas mais aplicações na cloud, as pessoas descobriram que esta decomposição da aplicação global em serviços independentes e focados em cenários é uma melhor abordagem a longo prazo.

Comparação entre abordagens de desenvolvimento de aplicações

Desenvolvimento de aplicações de plataforma do Service Fabric

  1. Uma aplicação monolítica contém funcionalidades específicas do domínio e é normalmente dividida em camadas funcionais, como Web, negócios e dados.

  2. Pode dimensionar uma aplicação monolítica ao cloná-la em vários servidores/máquinas virtuais/contentores.

  3. Uma aplicação de microsserviços separa a funcionalidade em serviços mais pequenos separados.

  4. A abordagem de microsserviços aumenta horizontalmente ao implementar cada serviço de forma independente, criando instâncias destes serviços em servidores/máquinas virtuais/contentores.

Conceber com uma abordagem de microsserviços não é adequado para todos os projetos, mas alinha-se mais com os objetivos empresariais descritos anteriormente. Começar com uma abordagem monolítica poderá fazer sentido se souber que terá a oportunidade de reformular o código mais tarde num design de microsserviços. Mais frequentemente, começa com uma aplicação monolítica e divide-a lentamente por fases, começando pelas áreas funcionais que precisam de ser mais dimensionáveis ou ágeis.

Quando utiliza uma abordagem de microsserviços, compõe a sua aplicação de muitos serviços pequenos. Estes serviços são executados em contentores implementados num cluster de máquinas. As equipas mais pequenas desenvolvem um serviço que se concentra num cenário e testa, versão, implementação e dimensiona de forma independente cada serviço para que toda a aplicação possa evoluir.

O que é um microsserviço?

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

  • Encapsular um cenário de cliente ou de negócio. Que problema está a resolver?
  • Desenvolvido por uma pequena equipa de engenharia.
  • Escrito em qualquer linguagem de programação, utilizando qualquer arquitetura.
  • Consiste em código e, opcionalmente, no estado, ambos com versões independentes, implementadas e dimensionadas.
  • Interagir com outros microsserviços através de interfaces e protocolos bem definidos.
  • Ter nomes exclusivos (URLs) que são utilizados para resolver a respetiva localização.
  • Mantenha-se consistente e disponível na presença de falhas.

Para somar:

As aplicações de microsserviços são compostas por pequenos serviços com controlo independente de versões e dimensionáveis direcionados aos clientes que comunicam entre si através de protocolos padrão com interfaces bem definidas.

Escrito em qualquer linguagem de programação, utilizando qualquer arquitetura

Enquanto programadores, queremos ser livres de escolher uma linguagem ou arquitetura, consoante as nossas competências e as necessidades do serviço que estamos a criar. Para alguns serviços, pode valorizar os benefícios de desempenho de C++ acima de qualquer outra coisa. Para outras pessoas, a facilidade de desenvolvimento gerido que obtém de C# ou Java pode ser mais importante. Em alguns casos, poderá ter de utilizar uma biblioteca de parceiros específica, tecnologia de armazenamento de dados ou método para expor o serviço aos clientes.

Depois de escolher uma tecnologia, tem de considerar a gestão operacional ou do ciclo de vida e o dimensionamento do serviço.

Permite que o código e o estado sejam versões, implementadas e dimensionadas de forma independente

Independentemente da forma como escreve os seus microsserviços, o código e, opcionalmente, o estado, deve implementar, atualizar e dimensionar de forma independente. Este problema é difícil de resolver porque se resume à sua escolha de tecnologias. Para dimensionar, compreender como particionar (ou fragmentar) o código e o estado é um desafio. Quando o código e o estado utilizam diferentes tecnologias, o que é comum atualmente, os scripts de implementação do seu microsserviço têm de conseguir dimensioná-los. Esta separação também tem a ver com agilidade e flexibilidade, pelo que pode atualizar alguns dos microsserviços sem ter de atualizar todos ao mesmo tempo.

Vamos voltar à nossa comparação das abordagens monolíticas e microsserviços por um momento. Este diagrama mostra as diferenças nas abordagens ao estado de armazenamento:

Armazenamento de estados para as duas abordagens

Armazenamento de estado da plataforma do Service Fabric

A abordagem monolítica, à esquerda, tem uma base de dados individual e camadas de tecnologias específicas.

A abordagem de microsserviços, à direita, tem um gráfico de microsserviços interligados onde o estado é normalmente confinado ao microsserviço e são utilizadas várias tecnologias.

Numa abordagem monolítica, a aplicação utiliza normalmente uma base de dados individual. A vantagem de utilizar uma base de dados é que está numa única localização, o que facilita a implementação. Cada componente pode ter uma única tabela para armazenar o respetivo estado. As equipas precisam de separar estritamente o estado, o que é um desafio. Inevitavelmente, alguém será tentado a adicionar uma coluna a uma tabela de clientes existente, a fazer uma associação entre tabelas e a criar dependências na camada de armazenamento. Depois de isto acontecer, não pode dimensionar componentes individuais.

Na abordagem de microsserviços, cada serviço gere e armazena o seu próprio estado. Cada serviço é responsável por dimensionar o código e o estado em conjunto para satisfazer as exigências do serviço. Uma desvantagem é que, quando precisar de criar vistas ou consultas dos dados da sua aplicação, tem de consultar vários arquivos de estado. Normalmente, este problema é resolvido por um microsserviço separado que cria uma vista numa coleção de microsserviços. Se precisar de executar múltiplas consultas improvisadas nos dados, deve considerar escrever os dados de cada microsserviço num serviço de armazenamento de dados para análise offline.

Os microsserviços têm um controlo de versão. É possível que diferentes versões de um microsserviço funcionem lado a lado. Uma versão mais recente de um microsserviço pode falhar durante uma atualização e ter de ser revertida para uma versão anterior. O controlo de versões também é útil para testes A/B, em que diferentes utilizadores experimentam versões diferentes do serviço. Por exemplo, é comum atualizar um microsserviço para um conjunto específico de clientes testarem novas funcionalidades antes de a implementarem mais amplamente.

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

Ao longo dos últimos 10 anos, foram publicadas extensas informações que descrevem padrões de comunicação em arquiteturas orientadas para o serviço. Geralmente, a comunicação de serviço utiliza uma abordagem REST com protocolos HTTP e TCP e XML ou JSON como formato de serialização. Do ponto de vista da interface, trata-se de seguir uma abordagem de web design. Mas nada deve impedi-lo de utilizar protocolos binários ou os seus próprios formatos de dados. Tenha em atenção que as pessoas terão mais dificuldades em utilizar os seus microsserviços se estes protocolos e formatos não estiverem disponíveis abertamente.

Tem um nome exclusivo (URL) utilizado para resolver a localização

O seu microsserviço tem de ser endereçável onde quer que esteja em execução. Se estiver a pensar nas máquinas e em qual está a executar um microsserviço específico, as coisas podem correr mal rapidamente.

Da mesma forma que o DNS resolve um URL específico para um computador específico, o seu microsserviço precisa de um nome exclusivo para que a localização atual seja detetável. Os microsserviços precisam de nomes endereçáveis que sejam independentes da infraestrutura em que estão a ser executados. Isto implica que existe uma interação entre a forma como o seu serviço é implementado e como é detetado, porque tem de existir um registo de serviço. Quando um computador falha, o serviço de registo tem de lhe indicar 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 num sistema distribuído. Grande parte do código que escrevemos como programadores é para processar exceções. Durante os testes, também passamos mais tempo no processamento de exceções. O processo está mais envolvido do que escrever código para processar falhas. O que acontece quando o computador no qual o microsserviço está em execução falha? Tem de detetar a falha, que é um problema difícil por si só. Mas também tem de reiniciar o seu microsserviço.

Para disponibilidade, um microsserviço tem de ser resiliente a falhas e ser capaz de reiniciar noutro computador. Além destes requisitos de resiliência, os dados não devem ser perdidos e os dados têm de permanecer consistentes.

A resiliência é difícil de alcançar quando ocorrem falhas durante uma atualização da aplicação. O microsserviço, que trabalha com o sistema de implementação, não precisa de recuperar. Tem de 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. Tem de considerar algumas perguntas, como se existem máquinas suficientes disponíveis para continuar a avançar e como recuperar versões anteriores do microsserviço. Para tomar estas decisões, precisa do microsserviço para emitir informações de estado de funcionamento.

Relatórios de estado de funcionamento e diagnóstico

Pode parecer óbvio e muitas vezes é negligenciado, mas um microsserviço precisa de comunicar o seu estado de funcionamento e diagnóstico. Caso contrário, tem pouca informação sobre o seu estado de funcionamento do ponto de vista das operações. Correlacionar eventos de diagnóstico num conjunto de serviços independentes e lidar com distorções do relógio da máquina para dar sentido à ordem dos eventos é um desafio. Da mesma forma que interage com um microsserviço através de protocolos e formatos de dados acordados, tem de uniformizar como registar eventos de estado de funcionamento e diagnóstico que acabarão num arquivo de eventos para consulta e visualização. Com uma abordagem de microsserviços, as diferentes equipas têm de concordar com um único formato de registo. Tem de existir uma abordagem consistente para ver eventos de diagnóstico na aplicação como um todo.

O estado de funcionamento é diferente dos diagnósticos. O estado de funcionamento é sobre o microsserviço que comunica o seu estado atual para tomar as medidas adequadas. Um bom exemplo é trabalhar com mecanismos de atualização e implementação para manter a disponibilidade. Embora um serviço possa estar atualmente em mau estado de funcionamento devido a uma falha no processo ou ao reinício do computador, o serviço ainda poderá estar operacional. A última coisa de que precisa é piorar a situação ao iniciar uma atualização. A melhor abordagem é investigar primeiro ou dar tempo para o microsserviço recuperar. Os eventos de saúde de um microsserviço ajudam-nos a tomar decisões informadas e, com efeito, ajudam a criar serviços de autorrecuperação.

Documentação de orientação para a conceção de microsserviços no Azure

Visite o centro de arquitetura do Azure para obter orientações sobre a criação e criação de microsserviços no Azure.

Service Fabric como uma plataforma de microsserviços

O Azure Service Fabric surgiu quando a Microsoft passou da entrega de produtos em caixa, normalmente monolíticos, para a prestação de serviços. A experiência de criar e operar grandes serviços, como a Base de Dados do 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 adotavam. O Service Fabric teve de ser executado não só no Azure, mas também em implementações autónomas do Windows Server.

O objetivo do Service Fabric é resolver os problemas difíceis de criar e executar um serviço e utilizar recursos de infraestrutura de forma eficiente, para que as equipas possam resolver problemas empresariais com uma abordagem de microsserviços.

O Service Fabric ajuda-o a criar aplicações que utilizam uma abordagem de microsserviços ao fornecer:

  • Uma plataforma que fornece serviços de sistema para implementar, atualizar, detetar e reiniciar serviços com falhas, detetar serviços, encaminhar mensagens, gerir estado e monitorizar o estado de funcionamento.
  • A capacidade de implementar aplicações em execução em contentores ou como processos. O Service Fabric é um orquestrador de contentores e processos.
  • APIs de programação produtiva para o ajudar a criar aplicações como microsserviços: ASP.NET Core, Reliable Actors e Reliable Services. Por exemplo, pode obter informações de estado de funcionamento e diagnóstico ou pode tirar partido da elevada disponibilidade incorporada.

O Service Fabric é agnóstico quanto à forma como cria o seu serviço e pode utilizar qualquer tecnologia. No entanto, fornece APIs de programação incorporadas que facilitam a criação de microsserviços.

Migrar aplicações existentes para o Service Fabric

O Service Fabric permite-lhe reutilizar o código existente e modernizá-lo com novos microsserviços. Existem cinco fases para modernização de aplicações e pode iniciar e parar em qualquer fase. As fases são:

  1. Comece com uma aplicação monolítica tradicional.
  2. Migrar. Utilize contentores ou executáveis convidados para alojar código existente no Service Fabric.
  3. Modernizar. Adicione novos microsserviços juntamente com o código contentorizado existente.
  4. Inovar. Divida a aplicação monolítica em microsserviços com base na necessidade.
  5. Transformar aplicações em microsserviços. Transforme aplicações monolíticas existentes ou crie novas aplicações greenfield.

Migração para microsserviços

Lembre-se de que pode começar e parar em qualquer uma destas fases. Não tem de avançar para a fase seguinte.

Vejamos exemplos para cada uma destas fases.

Migrate
Por dois motivos, muitas empresas estão a migrar aplicações monolíticas existentes para contentores:

  • Redução de custos, quer devido à consolidação e remoção do hardware existente, quer devido à execução de aplicações com maior densidade.
  • Um contrato de implementação consistente entre o desenvolvimento e as operações.

As reduções de custos são simples. Na Microsoft, muitas aplicações existentes estão a ser colocadas em contentores, o que leva a milhões de dólares em poupanças. A implementação consistente é mais difícil de avaliar, mas igualmente importante. Significa que os programadores podem escolher as tecnologias que lhes são adequadas, mas as operações aceitarão apenas um único método para implementar e gerir as aplicações. Alivia as operações de terem de lidar com a complexidade de suportar diferentes tecnologias sem forçar os programadores a escolher apenas determinadas. Essencialmente, todas as aplicações são colocadas em contentores em imagens de implementação autónomas.

Muitas organizações param aqui. Já têm os benefícios dos contentores e o Service Fabric fornece a experiência de gestão completa, incluindo implementação, atualizações, controlo de versões, reversões e monitorização do estado de funcionamento.

Modernizar
A modernização é a adição de novos serviços juntamente com o código contentorizado existente. Se vai escrever novo código, é melhor seguir pequenos passos no caminho dos microsserviços. Isto pode significar adicionar um novo ponto final da API REST ou uma nova lógica de negócio. Desta forma, vai iniciar o processo de criação de novos microsserviços e práticas de desenvolvimento e implementação dos mesmos.

Inove
Uma abordagem de microsserviços acomoda as necessidades empresariais em mudança. Nesta fase, tem de decidir se quer começar a dividir a aplicação monolítica em serviços ou a inovar. Um exemplo clássico aqui é quando uma base de dados que está a utilizar como uma fila de fluxo de trabalho se torna um estrangulamento de processamento. À medida que o número de pedidos de fluxo de trabalho aumenta, o trabalho tem de ser distribuído para dimensionamento. Tome essa parte específica da aplicação que não está a dimensionar ou que precisa de ser atualizada com mais frequência e divida-a como um microsserviço e inovar.

Transformar aplicações em microsserviços
Nesta fase, a sua aplicação é totalmente composta por microsserviços (ou divididos em). Para chegar a este ponto, fez o percurso dos microsserviços. Pode começar aqui, mas fazê-lo sem uma plataforma de microsserviços para o ajudar requer um investimento significativo.

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

Talvez. Na Microsoft, à medida que mais equipas começaram a criar para a cloud por motivos empresariais, muitas delas perceberam os benefícios de tomar uma abordagem semelhante a um microsserviço. O Bing, por exemplo, utiliza microsserviços há anos. Para outras equipas, a abordagem dos microsserviços era nova. O Teams descobriu que havia problemas difíceis de resolver fora das suas principais áreas de força. É por isso que o Service Fabric ganhou tração como tecnologia para criar serviços.

O objetivo do Service Fabric é reduzir as complexidades da criação de aplicações de microsserviços para que não tenha de passar por tantas remodelações dispendiosas. Inicie pequenos dimensionamentos quando necessário, pretera os serviços, adicione novos e evolua com a utilização do cliente. Também sabemos que existem muitos outros problemas ainda por resolver para tornar os microsserviços mais acessíveis para a maioria dos programadores. Os contentores e o modelo de programação de ator são exemplos de pequenos passos nessa direção. Temos a certeza de que surgirão mais inovações para facilitar uma abordagem de microsserviços.

Passos seguintes