Estilo de arquitetura de microsserviço

Azure

Uma arquitetura de microsserviços consiste em uma coleção de pequenos serviços autônomos. Cada serviço é independente e deve implementar uma única funcionalidade comercial em um contexto limitado. Um contexto limitado é uma divisão natural em uma empresa e fornece um limite explícito dentro do qual um modelo de domínio existe.

Diagrama lógico do estilo de arquitetura de microsserviços.

O que são microsserviços?

  • Os microsserviços são pequenos, independentes e fracamente acoplados. Uma única equipe pequena de desenvolvedores pode escrever e manter um serviço.

  • Cada serviço é uma base de código separado, que pode ser gerenciado por uma equipe de desenvolvimento pequena.

  • Os serviços podem ser implantados de maneira independente. Uma equipe pode atualizar um serviço existente sem recompilar e reimplantar o aplicativo inteiro.

  • Os serviços são responsáveis por manter seus próprios dados ou o estado externo. Isso é diferente do modelo tradicional, em que uma camada de dados separada lida com a persistência de dados.

  • Os serviços comunicam-se entre si por meio de APIs bem definidas. Detalhes da implementação interna de cada serviço ficam ocultos de outros serviços.

  • Suporte à programação poliglota. Por exemplo, os serviços não precisam compartilhar a mesma pilha de tecnologia, bibliotecas ou estruturas.

Além para os próprios serviços, alguns outros componentes aparecem em uma arquitetura de microsserviços típica:

Gerenciamento/orquestração. Esse componente é responsável por colocar serviços em nós, identificar falhas, rebalancear serviços entre nós e assim por diante. Normalmente, esse componente é uma tecnologia pronta para uso, como Kubernetes, em vez de algo criado de maneira personalizada.

Gateway de API. O gateway de API é o ponto de entrada para os clientes. Em vez de chamar serviços diretamente, os clientes chamam o gateway de API, que encaminha a chamada para os serviços adequados no back-end.

As vantagens de usar um gateway de API incluem:

  • Desacoplar os clientes dos serviços. Os serviços podem ter controle de versão ou ser refatorado sem necessidade de atualizar todos os clientes.

  • Os serviços podem usar protocolos de mensagens que não sejam amigáveis à Web, como AMQP.

  • O Gateway de API pode executar outras funções abrangentes, como autenticação, registro em log, terminação SSL e balanceamento de carga.

  • Políticas prontas para uso, como para limitação, cache, transformação ou validação.

Benefícios

  • Agilidade. Já que os microsserviços são implantados de forma independente, é mais fácil gerenciar correções de bugs e lançamentos de recursos. Você poderá atualizar um serviço sem reimplantar o aplicativo inteiro e, em seguida, reverter uma atualização se algo der errado. Em muitos aplicativos tradicionais, se um bug for encontrado em uma parte do aplicativo, ele poderá bloquear todo o processo de lançamento. Novos recursos poderão ser mantidos em espera até uma correção de bug ser integrada, testada e publicada.

  • Equipes pequenas e focadas. Um microsserviço deve ser pequeno o suficiente para que possa ser criado, testado e implantado por uma única equipe de recurso. Tamanhos pequenos de equipe promovem maior agilidade. Grandes equipes costumam ser menos produtivas, porque a comunicação é mais lenta, a sobrecarga de gerenciamento aumenta e a agilidade diminui.

  • Base de código pequena. Em um aplicativo monolítico, há uma tendência de que, ao longo do tempo, as dependências de código fiquem entrelaçadas. A adição de um novo recurso requer a alteração do código em muitos lugares. Não compartilhando código nem armazenamentos de dados, uma arquitetura de microsserviços minimiza as dependências, o que torna mais fácil adicionar novos recursos.

  • Combinação de tecnologias. Equipes podem escolher a tecnologia mais adequada para seu serviço, usando uma combinação de pilhas de tecnologia conforme apropriado.

  • Isolamento de falha. Se um microsserviço individual ficar indisponível, ele não interromperá o aplicativo inteiro, desde que os microsserviços upstream sejam projetados para lidar com falhas corretamente. Por exemplo, você pode implementar o padrão de Disjuntor ou pode projetar sua solução para que os microsserviços se comuniquem entre si usando padrões de mensagens assíncronas.

  • Escalabilidade. Os serviços podem ser dimensionados independentemente, permitindo que você escale horizontalmente subsistemas que exigem mais recursos, sem necessidade de escalar horizontalmente o aplicativo inteiro. Usando um orquestrador como o Kubernetes, você pode empacotar uma densidade maior de serviços em um único host, o que permite uma utilização mais eficiente dos recursos.

  • Isolamento de dados. É muito mais fácil executar atualizações de esquema, porque apenas um microsserviço é afetado. Em um aplicativo monolítico, atualizações de esquema podem se tornar muito difíceis porque todas as diferentes partes do aplicativo podem tocar os mesmos dados, o que torna a realização de qualquer alteração no esquema algo arriscado.

Desafios

Os benefícios de microsserviços têm um ônus. Veja alguns dos desafios a serem considerados antes de embarcar em uma arquitetura de microsserviços.

  • Complexidade. Um aplicativo de microsserviços tem mais partes móveis que o aplicativo monolítico equivalente. Cada serviço é mais simples, mas o sistema como um todo é mais complexo.

  • Desenvolvimento e teste. Escrever um serviço pequeno que precisa de outros serviços dependentes exige uma abordagem diferente de escrever um aplicativo monolítico ou em camadas tradicional. As ferramentas existentes não são necessariamente projetadas para funcionar com dependências de serviço. Refatorar entre limites de serviços pode ser difícil. Também pode ser um desafio testar as dependências de serviço, especialmente quando o aplicativo está evoluindo rapidamente.

  • Falta de governança. A abordagem descentralizada para compilar microsserviços tem vantagens, mas também pode causar problemas. Você pode acabar com muitos idiomas e estruturas diferentes que tornem difícil a manutenção do aplicativo. Pode ser útil estabelecer alguns padrões para todo o projeto, sem restringir excessivamente a flexibilidade das equipes. Isso se aplica especialmente a funcionalidades abrangentes como registro em log.

  • Latência e congestionamento de rede. O uso de muitos serviços granulares pequenos pode resultar em mais comunicação entre serviços. Além disso, se a cadeia de dependências de serviço ficar muito longa (o serviço A chamada o B, que chama o C…) a latência adicional poderá se tornar um problema. Você precisará projetar APIs com cuidado. Evite APIs excessivamente prolixas, pense em formatos de serialização e procure locais para usar padrões de comunicação assíncrona, como o nível de carregamento baseado em fila.

  • Integridade de dados. Cada microsserviço deve ser responsável pela própria persistência de dados. Assim, a consistência dos dados pode ser um desafio. Adote consistência eventual quando possível.

  • Gerenciamento. Ter êxito com microsserviços requer uma cultura DevOps madura. Registro em log correlacionado entre serviços pode ser desafiador. Normalmente, o registro em log deve correlacionar várias chamadas de serviço para uma operação de um único usuário.

  • Controle de versão. As atualizações de um serviço não devem interromper os serviços que dependem delas. Vários serviços podem ser atualizados a qualquer momento, portanto, sem design cuidadoso, você pode ter problemas com compatibilidade com versões anteriores ou futuras.

  • Conjunto de qualificações. Os microsserviços são sistemas altamente distribuídos. Avalie cuidadosamente se a equipe tem as habilidades e a experiência para ser bem-sucedida.

Práticas recomendadas

  • Modele os serviços em torno de domínio da empresa.

  • Descentralize tudo. Equipes individuais são responsáveis por projetar e criar serviços. Evite compartilhar esquemas de dados ou códigos.

  • O armazenamento de dados deve ser privado para o serviço que é o proprietário dos dados. Use o melhor armazenamento para cada serviço e tipo de dados.

  • Os serviços comunicam-se por meio de APIs bem projetadas. Evite o vazamento de detalhes da implementação. As APIs devem modelar o domínio, não a implementação interna do serviço.

  • Evite acoplamento entre serviços. Causas de acoplamento incluem protocolos de comunicação rígidos e esquemas de banco de dados compartilhados.

  • Descarregue preocupações abrangentes, como autenticação e terminação SSL, para o gateway.

  • Mantenha o conhecimento de domínio fora do gateway. O gateway deve tratar e rotear solicitações de cliente sem qualquer conhecimento das regras de negócios ou da lógica do domínio. Caso contrário, o gateway se tornará uma dependência e poderá causar um acoplamento entre serviços.

  • Os serviços devem ter um acoplamento flexível e alta coesão funcional. Funções que provavelmente mudarão juntas devem ser empacotadas e implantadas juntas. Se residirem em serviços separados, esses serviços acabarão sendo fortemente acoplados, porque uma alteração em um serviço exigirá atualizar outro. Uma comunicação excessivamente prolixa entre dois serviços pode ser um sintoma de acoplamento forte e coesão baixa.

  • Isole falhas. Use estratégias de resiliência para impedir que falhas em um serviço distribuam-se em cascata. Confira Padrões de resiliência e Design de aplicativos resilientes.

Próximas etapas

Para obter orientações detalhadas sobre como criar uma arquitetura de microsserviços no Azure, consulte Projetar, criar e operar microsserviços no Azure.