Microservice: Todo mundo comete erros – Parte 1

Todo mundo comete erros. Os sábios não são aqueles que nunca cometem erros, mas aqueles que se perdoam e aprendem com seus erros.” — Ajahn Brahm (físico teórico, autor, e monge Budista)

Hoje em dia, o padrão microservice [1] é um tema recorrente, que tem uma enorme influência em todos os tipos de programas e projetos de engenharia de software. No entanto, nos últimos dois anos, houve uma reação notável contra os microservices [2]. Por exemplo, [3] concluiu: “devido aos requisitos de custo e maturidade organizacional, os microservices provavelmente nunca chegarão à fase de adoção” enquanto [2] compartilhou um testemunho de um CTO de uma grande companhia “Trocamos uma pilha enorme de lixo por centenas de pilhas menores”.

A maioria das causas-raízes dessa reação não deve ser atribuída ao padrão microservice, mas, sim, aos erros cometidos durante o projeto de aplicação e de arquitetura, assim como suas consequências na implementação e operação. Tais causas podem ser agrupadas em duas categorias amplas: (A) os erros na aplicação do padrão microservice e (B) a negligência da maturidade organizacional necessária, que inclui, pelo menos: deficiências de recursos de teste, insuficiências de capacidades DevOps e desafios organizacionais (por exemplo, a falta da organização de equipes em torno de capacidades de negócios).

A presente série está focada nos erros na aplicação do padrão microservice, fornecendo, talvez, para pessoas sábias, um atalho para “aprenderem com seus erros” (se atalhos existem). A primeira parte é focada nos erros no projeto de aplicações, enquanto a segunda parte está focada nos erros de arquitetura.

Primeiro erro – O evitar da “Visão Correta” ou desalinhamento com o negócio

Projete o aplicativo usando um conjunto de microservices, que estão bem alinhados com as capacidades de negócios. Embora relacionado à maturidade organizacional, vale a pena organizar equipes em torno de tais capacidades de negócios e os serviços que as apoiam.

Prefira a definição do escopo dos microservices em torno das capacidades de negócios. Evite tecnicismos na definição de escopo dos microservices, por exemplo, a regra “10 a 100 linhas de código” [4] ou declarações compartilhadas, durante uma sessão de design, como “Cada microservice deve lidar com uma tabela“.

Segundo erro – O evitar do “Caminho do Meio” ou sobre o tamanho errado do escopo dos microservices

[5] argumentou que não há nenhuma regra mágica para dividir uma aplicação em microservices, ou para definir o escopo ideal deles. No entanto, a literatura sugere o seguinte gráfico para mostrar a influência do número de microservices no custo total de um software.

De acordo com [5], é razoável que a divisão de uma aplicação em muitos microservices (escopo é muito pequeno) tem um enorme impacto sobre o custo total. No entanto, em vez de um impacto positivo – como ingenuamente aceito – pode ser um impacto negativo se o valor no eixo x (número de módulos) não está localizado na região de custo mínimo. O mesmo efeito indesejável ocorre quando há poucos microservices (escopo é muito grande).

Na verdade, o gráfico é uma otimização da curva U, na qual não é obrigatório encontrar o ponto perfeito para capturar a maior parte do valor, mas, sim, trabalhar pela coesão, enquanto o primeiro erro é evitado.

Por fim, lembre-se [2]: “a comunicação excessiva entre os serviços pode ser um sinal de que o escopo dos serviços não foi devidamente definido, e, portanto, eles são acoplados“.

Terceiro erro – O evitar do “Esforço Correto” ou da falta de projeto adequado

Os microservices integram-se através de APIs, não somente através de transportes síncronos como APIs REST/HTTP, utilizando contratos. Portanto, “abordagem de contrato em primeiro lugar” (contract-first) é a maneira preferível de projetar microservices.

Tal ênfase nos contratos coloca desafios para o projeto, em particular, (1) uma boa compreensão da capacidade de negócio atribuída a um determinado microservice, bem como (2) os casos-de-uso dos consumidores de tal API devem ser considerados. Este último aspecto, a ênfase nos consumidores, refere-se diretamente a um erro de design bem conhecido apontado há mais de 15 anos pelo Gartner [6]: “a prática do “domain model dumping ” é o flagelo de APIs mal projetadas nos próximos anos“.

Domain model dumping” é o projeto de microservices expondo a riqueza do domínio (ênfase no provedor) sem levar em conta as necessidades dos consumidores, como resultado, uma API supercomplicada é exposta, que por sua vez acopla desnecessariamente provedores e consumidores. A regra geral é “não pratique domain model dumping“.

Um erro adicional no projeto de uma API orientada para ao consumidor é a mistura de dados mestres e transacionais em um microservice que suporta uma dada capacidade de negócio. Por exemplo, em um aplicativo de comércio eletrônico, um determinado consumidor precisa dos dados de pedidos, bem como dos dados do produto em tal pedido. Pode-se definir o contrato do microservice de pedido para expor tais dados agregados (pedido e produtos), no entanto, essa mistura de dados de transação (pedido) e dados mestres (produto) tem efeitos colaterais tremendos, por exemplo, acoplamento desnecessário de serviços de pedidos e produtos, possível degradação do tempo de resposta e da resiliência dos serviços, … Um erro muito relacionado é a aplicação geral de “embedding” no contrato de um microservice. De fato, a combinação de dados mestre e transacionais geralmente leva à “embedding“.

Grosso modo, as relações de dados em um determinado contrato de um microservice podem ser projetadas usando três técnicas, a saber “links“, “sideloading” e “embedding” [7]. Essas técnicas oferecem diferentes compromissos entre largura de banda (tamanho da carga útil), chatting (número de requisições), desacoplamento e facilidade de uso. Os “links” baseiam-se na opção por fornecer uma chave estrangeira para links de dados ou hipermídia, de modo que se concentram principalmente na largura de banda e no desacoplamento. O “sideloading” prefere desacoplar os dados e otimizar a largura de banda assim como o chatting em favor da facilidade de uso pelo consumidor (no exemplo anterior, um agregado é definido para compor produtos e pedidos sem o “embedding” dos dados agregados). Por fim, a técnica “embedding” prefere unir os dados (no exemplo anterior, um pedido pode ter uma dependência explícita de um produto incorporado nele) e concentrar-se em ser amigável ao consumidor, apesar do sacrifício da largura de banda e do chatting. Em geral, o uso da técnica de “embedding” em um microservice que oferece suporte à uma capacidade de negócio é um sinal de que o microservice não foi projetado adequadamente e, portanto, é acoplado comprometendo a capacidade de resposta e a resiliência.

Conclusão

A primeira parte da série ” Microservice: Todo mundo comete erros” apresentou os três erros mais comuns e gerais cometidos no uso do padrão microservice em relação ao projeto de aplicações. Talvez, para pessoas sábias, eles são um atalho para “aprender com seus erros” seguindo o “Caminho do Meio” e dois dos oito caminhos, a saber, “Visão Correta” e “Esforço Correto“.

A segunda parte trata de erros de projeto de arquitetura, onde todos estão relacionados com as falácias da computação distribuída [5].

Referências

[1] Pattern: Microservice Architecture

[2] Microservices Done Right, Part 1: Avoid the Antipatterns!

[3] Microservices to Not Reach Adopt Ring in ThoughtWorks Technology Radar

[4] Services, Microservices, Nanoservices — oh my!

[5] Mesoservice pattern or ‘pluralitas non est ponenda sine neccesitate

[6] … Don´t forget about design