Top 10 Anti-Padrões de Microsserviços

Dez anti-padrões comuns e como evitá-los

Top 10 Anti-Padrões de Microsserviços
Photo by Etienne Girardet / Unsplash

Introdução

Uma aplicação baseada em uma arquitetura de microsserviços bem construída pode resistir ao teste do tempo, sendo escalável, flexível e resiliente à maioria dos problemas que possam surgir.

Essas arquiteturas alcançam um alto nível de resiliência devido aos seus componentes fracamente acoplados que podem ser executados independentemente, não sendo afetados por outros microsserviços dentro da aplicação.

Dito isso, sempre há maneiras de uma arquitetura de microsserviços falhar e se tornar ineficaz.

Neste artigo, vamos analisar alguns dos anti-padrões ou padrões de design mais comuns que podem causar problemas em uma arquitetura baseada em microsserviços.

Se você quiser um resumo, aqui está uma lista dos anti-padrões:

  1. Monólito em Microsserviços
  2. Microsserviços Conversadores
  3. Monólito Distribuído
  4. Excesso de Microsserviços
  5. Violação da Responsabilidade Única
  6. Arquitetura Espaguete
  7. Inconsistência de Dados Distribuídos
  8. Acoplamento Rígido
  9. Falta de Observabilidade
  10. Ignorando os Custos Humanos

1. Monólito em Microsserviços

Se você está tentando construir microsserviços enquanto preserva uma arquitetura de monólito, você terá problemas com escalabilidade, tolerância a falhas e muito mais. Isso muitas vezes é causado por:

  • Bancos de Dados Compartilhados: Ao construir microsserviços, é frequentemente uma boa ideia ter um banco de dados por serviço. Isso permite controlar o tipo de banco de dados, regras de esquema e capacidade de IOPS por regra de serviço, permitindo um controle mais preciso da escalabilidade. Mas, se você usar um único banco de dados para todos os seus serviços, tornará mais difícil o crescimento do seu aplicativo.
  • Implantação Complexa: Apesar de serem decompostos em serviços menores, o processo de implantação ainda é complicado e demorado, exigindo coordenação entre várias equipes e envolvimento manual. Isso limita a agilidade e flexibilidade alcançadas pela implementação de microsserviços.
  • Fronteiras de Serviço Inadequadas: Fronteiras de serviço mal especificadas resultarão em funcionalidades sobrepostas e propriedade indefinida. Isso pode levar à duplicação de trabalho e dificuldades no controle e melhoria da arquitetura. Portanto, para evitar ter monólitos em microsserviços, eu recomendaria seguir em frente com um banco de dados único por microsserviço, juntamente com a definição clara da propriedade dos seus microsserviços por meio de um Design Orientado por Domínio.
Developing a DDD-Oriented Microservices
Microservices architecture and Domain-Driven Design (DDD) are predicted to continue gaining significant popularity in software development. Combining these powerful approaches enables teams to build…

2. Microsserviços Conversadores

Devido à sua natureza desacoplada, os microsserviços frequentemente se comunicam entre si para processar a carga de trabalho da aplicação. Embora a comunicação seja essencial, uma comunicação excessiva ou ineficiente entre os microsserviços os tornará menos eficientes. Vamos analisar alguns cenários que podem diminuir significativamente a eficiência e contribuir para microsserviços conversadores:

  • Comunicação Inter-Serviço Frequente: Casos em que os microsserviços dentro do sistema enviam um grande número de solicitações a outros microsserviços para realizar tarefas menores ou obter pequenas quantidades de dados. Isso pode gerar um grande tráfego de rede e aumentar o atraso de resposta.
  • API's de Granularidade Fina: Microsserviços fornecem API's de granularidade fina que exigem várias chamadas para concluir uma única solicitação do usuário ou transação comercial. Cada chamada pode exigir serialização, sobrecarga de rede e até mesmo operações de E/S bloqueantes, aumentando os problemas de desempenho.
  • Cascata de Chamadas: Uma única solicitação do usuário ou transação inicia uma série de chamadas entre vários microsserviços, sendo que cada serviço depende dos outros para concluir seu processamento. Isso pode causar um efeito dominó, no qual a falha ou atraso de um serviço se espalha para outros, resultando em deterioração em todo o sistema.

Portanto, para evitar esse problema, você precisará projetar sua arquitetura de forma que seus serviços sejam desacoplados e mais escaláveis. Você pode introduzir filas de mensagens, barramentos de eventos ou tópicos de eventos usando serviços como Amazon SQS, Amazon SNS e Amazon EventBridge por exemplo.

Como você pode ver, o Microsserviço de Confirmação de Pedido se comunica com os Microsserviços de Remessa, Inventário e Notificação. No entanto, ele não se comunica diretamente com esses serviços. Em vez disso, ele usa serviços intermediários como SQS e SNS para desacoplar o comportamento de comunicação.

Fazendo isso, você pode trabalhar com a comunicação entre os seus serviços de forma desacoplada.

3. Monólito Distribuído

Este anti-padrão refere-se a uma aplicação que é projetada e implementada como um sistema distribuído, mas é composta por vários componentes ou serviços interconectados que estão fortemente acoplados e, portanto, os microsserviços não possuem verdadeira independência.

Algumas das principais características desse anti-padrão incluem:

  • Falta de Autonomia de Serviço: Cada componente do sistema distribuído não possui autonomia completa, pois depende muito de outros componentes para sua operação. Essa falta de independência torna desafiador escalar, implantar e evoluir diversos elementos de forma independente.
  • Interdependências Complexas: Os componentes do sistema distribuído possuem interdependências complicadas, com um dependendo de vários outros para funcionar corretamente. Isso resulta em uma teia de relacionamentos difícil de gerenciar e entender, aumentando a complexidade e o risco.
  • Compartilhamento de Estado: Os componentes de um sistema distribuído compartilham estado ou dados diretamente, seja por meio de bancos de dados compartilhados, caches ou comunicação direta. Esse estado compartilhado pode causar desafios de consistência de dados, condições de corrida e dificuldades de escala.

Por exemplo, considere esta arquitetura:

Você está invocando três serviços - OrderService, PaymentService e InvoiceService. Esses três serviços são feitos para funcionar de forma independente, mas encadeando a invocação dessa forma, você está acoplando os serviços a essa única operação. Ao fazer isso, você introduz problemas como escalabilidade linear e cria interdependências desnecessárias.

Novamente, você pode se livrar desse problema desacoplando seus microsserviços com serviços como SNS, SQS.

4. Excesso de Microsserviços

Um dos equívocos mais comuns ao projetar arquiteturas baseadas em microsserviços é dividir cada função em um microsserviço, até mesmo as mais simples!

Isso introduz microsserviços onde não são necessários e vai além do que é necessário ou benéfico, prejudicando o desempenho geral da aplicação. É crucial dividir os microsserviços com base no que é necessário, seguindo os princípios do Design Orientado por Domínio.

As principais características do anti-padrão "Excesso de Microsserviços" incluem:

  • Fragmentação Excessiva: O sistema é dividido em um número significativo de microsserviços, o que pode resultar em dezenas ou até centenas de serviços. Cada microsserviço pode encapsular apenas uma pequena parte da funcionalidade, resultando em uma decomposição excessivamente granular.
  • Baixa Coesão: Os microsserviços individuais não possuem coesão, ou seja, podem não incluir conjuntos de funcionalidades logicamente conectados ou coerentes. Isso pode levar a uma lógica de negócios dispersa e fragmentada, tornando difícil compreender e gerenciar o sistema como um todo.
  • Alto Acoplamento: Apesar de serem divididos em microsserviços, os serviços podem estar fortemente acoplados devido a interações e interdependências significativas entre eles. Alterações em um microsserviço podem exigir alterações em muitos outros microsserviços, aumentando a complexidade e o risco.

Uma maneira de resolver esse problema é adotar o Design Orientado por Domínio em seus microsserviços e criar microsserviços para domínios específicos do seu aplicativo. Para um guia detalhado sobre DDD, confira isso:

Developing a DDD-Oriented Microservices
Microservices architecture and Domain-Driven Design (DDD) are predicted to continue gaining significant popularity in software development. Combining these powerful approaches enables teams to build…

5. Violação da Responsabilidade Única

Isso é uma violação fundamental da responsabilidade de uma função em um design orientado a objetos. Acontece quando uma única função ou microsserviço assume múltiplas responsabilidades ou preocupações que idealmente deveriam ser separadas. Por exemplo, quando um microsserviço de processamento de pagamentos também lida com o registro de usuários.

Vamos analisar alguns cenários que promovem esse anti-padrão:

  • Falta de Conhecimento de Princípios de Design: Os desenvolvedores podem não estar totalmente cientes ou compreender conceitos de design como o Princípio da Responsabilidade Única (SRP), ou podem falhar em priorizar sua aplicação dentro do código-base.
  • Planejamento Inadequado: Planejamento ou análise inadequados nas fases iniciais do design de software podem resultar em uma delimitação pouco clara das funções dos componentes, levando à mistura de várias preocupações dentro do mesmo componente.
  • Interpretação Errada de Requisitos: Mal-entendimento ou interpretação errada de requisitos pode resultar na introdução de funcionalidades desnecessárias ou irrelevantes dentro de um componente, violando o Princípio da Responsabilidade Única (SRP).

6. Arquitetura Espaguete

Alguns anti-padrões são autoexplicativos, como a Arquitetura Espaguete, que se refere a uma arquitetura de software que não possui uma estrutura e organização clara, resultando em uma confusão de componentes, módulos ou camadas interconectados.

As principais características do anti-padrão "Arquitetura Espaguete" incluem:

  • Falta de Separação de Responsabilidades: A arquitetura não consegue separar entre diferentes responsabilidades, levando à mistura de lógica de negócios, lógica de apresentação, lógica de acesso a dados e outras funcionalidades dentro do mesmo componente ou módulo.
  • Fluxo de Controle Complexo: O fluxo de controle da arquitetura é complicado e confuso, com dependências e interações entre componentes difíceis de rastrear ou compreender. Isso pode resultar em comportamento imprevisível e consequências indesejadas.
  • Alto Acoplamento: Semelhante ao que vimos anteriormente, os componentes ou módulos dentro da arquitetura estão intimamente conectados, o que significa que eles são extremamente dependentes um do outro. Alterações em um componente às vezes exigem alterações em vários outros componentes, causando um efeito cascata em todo o sistema.

7. Inconsistência de Dados Distribuídos

Isso ocorre quando os dados são replicados em vários nós ou serviços, e inconsistências surgem devido a atrasos ou falhas na sincronização das atualizações dessas réplicas, o que leva a informações incorretas ou desatualizadas sendo acessadas por diferentes partes do sistema, resultando em comportamento incorreto, corrupção de dados ou violações de integridade.

As principais características do anti-padrão "Inconsistência de Dados Distribuídos" incluem:

  • Atualizações Assíncronas: As atualizações de dados se propagam de forma assíncrona pelas réplicas ou nós do sistema distribuído. Isso pode causar atrasos entre a execução de uma alteração e sua refletividade em todas as cópias dos dados.
  • Partições de Rede: Partições ou falhas de rede podem ocorrer por motivos imprevistos, impedindo que as atualizações se propaguem para todas as réplicas ou resultando em discrepâncias entre as réplicas devido a atualizações incompletas.
  • Operações Conflitantes: Operações simultâneas nos mesmos dados de vários nós podem causar conflitos que não são adequadamente tratados, resultando em dados inconsistentes ou danificados.

Para corrigir esses problemas, é importante aproveitar padrões de microsserviços, como o Padrão de Saga, para criar e gerenciar transações distribuídas em seus microsserviços.

How to Use Saga Pattern in Microservices
Using the Saga pattern in Microservice transactions

8. Acoplamento Rígido

O acoplamento rígido pode não ser visto como um anti-padrão por si só, mas é uma característica chave em muitos dos anti-padrões que vimos anteriormente. No entanto, ter microsserviços fortemente dependentes uns dos outros ou de suas saídas pode causar problemas no sistema ao escalá-lo.

Isso contribui para muitos anti-padrões, como, mas não se limitando a:

  • Arquitetura Monolítica
  • Arquitetura Espaguete
  • Objeto Deus
  • Inconsistência de Dados Distribuídos
  • Dependência de Fornecedor

9. Falta de Observabilidade

Isso ocorre quando a aplicação não fornece insights adequados sobre o estado interno, operações e desempenho. Isso torna desafiador para desenvolvedores ou administradores observar o desempenho da aplicação ou mesmo solucionar eficientemente um problema.

As principais características do anti-padrão "falta de observabilidade" incluem:

  • Registro Limitado: O sistema carece de mecanismos abrangentes de registro para capturar eventos, erros e ações significativas que ocorrem nele. Isso dificulta o rastreamento do fluxo de execução e a identificação de problemas.
  • Métricas Inadequadas: O sistema não fornece métricas úteis ou dados de telemetria sobre seu desempenho, uso de recursos e outros indicadores importantes. Sem essas informações, é difícil avaliar a saúde do sistema e identificar possíveis gargalos ou áreas de melhoria.
  • Rastreamento Esparsa: O sistema carece de capacidades de rastreamento distribuído para rastrear o fluxo de solicitações e transações em muitos serviços ou componentes. Isso dificulta a detecção de picos de desempenho, problemas de latência e falhas em sistemas distribuídos.

Considere o uso de ferramentas nativas em nuvem, como AWS X-Ray, ou plataformas de terceiros, como New Relic.

Debug Tool - AWS X-Ray - AWS
AWS X-Ray helps you debug and analyze your microservices applications with request tracing so you can find the root cause of issues and performance bottlenecks.
Monitor, Debug and Improve Your Entire Stack
Sign up for free, no credit card required. Get Instant Observability with New Relic One and Quickstarts that make it easy to instrument in a few clicks.

Fazendo isso, você pode obter insights importantes sobre erros do sistema e identificar problemas de desempenho e escalabilidade de maneira proativa.

10. Ignorando os Custos Humanos

Isso ocorre quando o objetivo principal está focado em atender a objetivos técnicos e prazos sem considerar adequadamente o impacto no bem-estar, moral e equilíbrio entre trabalho e vida pessoal da equipe ou indivíduos envolvidos no projeto.

As principais características do anti-padrão "ignorando os custos humanos" incluem:

  • Excesso de Trabalho: Os membros da equipe são frequentemente obrigados a trabalhar horas extras, incluindo noites, fins de semana e feriados, para cumprir prazos do projeto ou resolver desafios não previstos. Isso pode causar exaustão, cansaço e diminuição da produtividade.
  • Expectativas Irrealistas: Prazos e entregas do projeto são definidos sem considerar os recursos, habilidades ou capacidades existentes da equipe. Isso cria expectativas irrealistas e coloca pressão desnecessária sobre os membros da equipe para executar sob prazos apertados.
  • Microgerenciamento: Gerentes ou líderes de equipe exercem controle excessivo ou microgerenciamento sobre o trabalho dos membros da equipe, o que mina a autonomia, criatividade e motivação.
  • Falta de Suporte: Quando confrontados com problemas ou dificuldades no trabalho, os membros da equipe se sentem sem suporte da gerência ou colegas. Isso pode aumentar sentimentos de solidão, tensão e desengajamento.

Conclusão

Analisamos alguns dos anti-padrões mais comuns que podem ser observados em organizações que estão começando sua jornada com microsserviços ou estão evoluindo suas práticas de arquiteturas mais tradicionais.

Esses anti-padrões não apenas criam gargalos em aplicações, mas também as fazem ter um desempenho inferior e travar devido às várias restrições introduzidas devido a más práticas seguidas.

Portanto, devemos evitar tais problemas para garantir que nossas arquiteturas de microsserviços funcionem conforme o esperado, permitindo escalabilidade, flexibilidade e resiliência.

Espero que você tenha achado isso útil.

Obrigado por ler!


Este é um artigo traduzido. O artigo original pode ser lido no link abaixo.

Top 10 Microservice Anti-Patterns
Ten Common Anti-Patterns and How to Avoid Them