BT

Disseminando conhecimento e inovação em desenvolvimento de software corporativo.

Contribuir

Tópicos

Escolha a região

Início Artigos Service Mesh: Promessa ou Risco?

Service Mesh: Promessa ou Risco?

Pontos Principais

  • As três estratégias principais para gerenciar falhas em uma arquitetura de microservices são: teste proativo, mitigação e resposta rápida.
  • Se temos um número pequeno de microservices ou uma topologia rasa, considere postergar a adoção do service mesh, e avalie estratégias alternativas para o gerenciamento de falhas.
  • Se você está implantando um framework de service mesh, prepare-se para investir esforço contínuo em integrar o framework no seu ciclo de vida do desenvolvimento de software.

Os frameworks de Service Mesh como o Istio, o Linkerd, e o Cilium estão ganhando grande visibilidade ao passo que os microservices são adotados pelas empresas. Os argumentos para adotar service mesh são convincentes: observabilidade full-stack, segurança transparente, resiliência de sistemas, entre outros. Mas será que o service mesh é realmente a solução certa para a sua aplicação nativa na nuvem? Este artigo vai ajudar a entender quando usar um service mesh faz sentido e quando não faz.

Microservices, feitos da forma correta, permitem rápida evolução

Hoje em dia, o time to market é uma vantagem competitiva fundamental. Responder rapidamente às forças de mercado e ao feedback do cliente é crucial para construir uma empresa de sucesso. O paradigma de Microservices é poderoso para acelerar a agilidade do software e velocidade do workflow. Ao empoderar diferentes times de software para trabalhar simultaneamente em partes diferentes de uma aplicação, a tomada de decisão se torna descentralizada.

A tomada de decisão descentralizada tem duas consequências importantes. A primeira, os times de software podem tomar decisões locais otimizadas sobre a arquitetura, a publicação, os testes e etc., ao invés de depender de um padrão de otimização global. O exemplo mais comum deste tipo de decisão de lançamento é: ao invés de orquestrar a publicação de uma única aplicação monolítica, cada time tem seu próprio meio de publicação. A segunda consequência é que a tomada de decisão pode acontecer de forma mais rápida, conforme o número de saltos de comunicação entre times de software e funções centralizadas como as operações, a arquitetura e etc. são reduzidos.

Microservices não são de graça, eles introduzem novas formas de falha

Adotar a arquitetura de microservices tem trazido diversas implicações para as organizações, processos, e arquitetura. Este artigo foca em uma das principais mudanças arquiteturais, a de que microservices é um sistema distribuído. Em uma aplicação baseada em microservices, a lógica de negócios é distribuída entre múltiplos serviços que se comunicam entre si através da rede. Um sistema distribuído tem muito mais formas de falhar, como demonstrado no artigo falácias da computação distribuída.

Dadas as formas de falha, é crucial ter uma arquitetura e processos que previnam pequenas falhas de se tornarem grandes falhas. Na velocidade do dia-a-dia, falhas são inevitáveis, falhas são inseridas conforme os serviços são atualizados, serviços irão falhar na inicialização e assim por diante.

Na evolução das aplicações a complexidade aumenta e a necessidade de gerenciamento de falhas torna-se obrigatória. Quando uma aplicação consiste em muitos microservices, as falhas tendem a ser facilmente isoladas e tratadas. Conforme as aplicações crescem em dezenas ou centenas de microservices, e com times diferentes distribuídos geograficamente, os sistemas de gerenciamento de falhas devem escalar junto às aplicações.

Gerenciamento de Falha

Estas são 3 estratégias básicas para gerenciamento de falhas: teste proativo, mitigação, e resposta rápida.

  1. Teste Proativo. Implementar processos e sistemas para testar aplicações e serviços a fim de identificar as falhas com antecedência e com frequência. A "Garantia de qualidade" (Quality Assurance) clássica está incluída nesta categoria, e apesar dos times de testes tradicionais serem focados em testes pré-publicação, estes agora se estendem frequentemente para testes em produção.
  2. Mitigar. Implementar estratégias para reduzir o impacto de qualquer tipo de falha. Por exemplo, o balanceamento de carga entre múltiplas instâncias de um serviço assegura que se esta única instância falhar, todo o serviço pode continuar respondendo.
  3. Respostas rápidas. Implementar processos e sistemas para identificar e endereçar as falhas rapidamente.

Service mesh

Quando um serviço falha, isto causa um impacto nos serviços upstream e downstream. O impacto desta falha no serviço pode ser facilmente evitado ao gerenciar propriamente a comunicação entre os serviços. Neste momento entra um framework Service Mesh.

Um framework service mesh gerencia a comunicação a nível de serviço (ex: Layer 7) e fornece primitivos poderosos que podem ser usados nas três estratégias de gerenciamento de falhas. Os frameworks de service mesh implementam:

  1. Roteamento dinâmico, que pode ser usado por estratégias diferentes de release e teste como roteamento canário, traffic shadowing ou implantação blue/green.
  2. Resiliência, que mitiga o impacto de falhas através de estratégias como circuit break e rate limit.
  3. Observabilidade, que ajuda a melhorar o tempo de resposta ao coletar métricas e adicionar contexto (ex: rastreamento de dados) para a comunicação serviço-a-serviço.

Os frameworks de service mesh adicionam estas características de forma amplamente transparente para os desenvolvedores de aplicações. Contudo, como veremos neste artigo, existem algumas nuances para esta noção de transparência.

O service mesh ajudará a construir softwares mais rápido?

Ao decidir quando ou não o service mesh faz sentido para a organização, comece por duas questões.

  1. Quão complexa é a topologia de serviços da empresa?
  2. Como será possível integrar um framework de service mesh no ciclo de desenvolvimento de sistemas?

A topologia de serviços

Normalmente, uma organização começa com um único microservice que se conecta com uma aplicação monolítica existente. Nesta situação, os benefícios do service mesh são um tanto limitados. Se o microservice falha, identificar a falha é simples. O impacto de uma única falha de microservice é inerentemente limitado. Publicações incrementais podem também ser conseguidas através de sua infraestrutura existente como o Kubernetes ou seu API Gateway.

Conforme a topologia de serviços cresce em tamanho e complexidade, os benefícios do service mesh começam a acumular. O ponto chave limitante a considerar é a profundidade da cadeia de chamadas do serviço. Se a topologia é rasa, onde o monolito chama diretamente dúzias de microservices, os benefícios do service mesh são ainda bastante limitados. Conforme mais comunicações serviço-a-serviço são introduzidas, onde o serviço A chama o serviço B, que por sua vez chama o serviço C, o service mesh se torna mais importante.

Integrando service mesh ao SDLC

Um framework service mesh tem seu design definido para ser transparente para os serviços atuais que são executados na malha. Uma forma de pensar em service mesh é como uma rede L7 rica. Nenhuma alteração em código é necessária para um serviço rodar em um service mesh.

No entanto, implementar um framework de service mesh não torna automaticamente o software mais rápido e ágil. É necessário que se integre o service mesh no processo de desenvolvimento.

Implementando estratégias de gerenciamento de falhas como parte do SDLC

Um service mesh fornece poderosos primitivos para o gerenciamento de falhas, mas existem alternativas ao service mesh. Nesta seção falaremos sobre cada estratégia de gerenciamento de falhas, e discutiremos sobre como aplicar ao SDLC

Testes Proativos

As estratégias de teste para um microservice devem ser as mais próximas possíveis de casos reais. Dada a complexidade de uma aplicação multi-serviço, estratégias de testes contemporâneas enfatizam testes em produção (ou com dados de produção).

Um service mesh permite testes em produção por controlar o fluxo de tráfego da camada L7 para os serviços. Por exemplo, um service mesh pode rotear 1% do tráfego para a versão 1.1 de um serviço e 99% do tráfego para a versão 1.0 (uma publicação canário). Estas capacidades são expostas através de regras de roteamento declarativas (ex.: linkerd dtab ou Istio routing rules).

Um service mesh não é a única forma de testar proativamente. Outras estratégias complementares incluem usar um gerenciador de contêineres como o Kubernetes para fazer um rolling update, um API Gateway que pode fazer implantações canário, ou a engenharia do caos.

Com todas estas estratégias, se torna aparente a questão de quem gerencia o fluxo de testes. Em um framework service mesh, as regras de roteamento podem ser gerenciadas de forma centralizada pelo mesmo time que o gerencia. Contudo, provavelmente não irá escalar, pois presume-se que o(s) autor(es) de serviços individuais vão querer ter controle de quando e como irão liberar as versões de seus serviços. Então se os autores dos serviços gerenciam as regras de roteamento, como educá-los no que eles podem ou não fazer? Como gerenciar regras de roteamento conflitantes?

Mitigação

Um serviço pode falhar por vários motivos: um erro no código, recursos insuficientes, falha de hardware, entre diversos outros motivos. Limitar o impacto de uma falha em um serviço é importante para que toda a aplicação continue funcionando, embora em um estado degradado.

Um framework service mesh mitiga o impacto de uma falha ao implementar padrões de resiliência como balanceamento de carga, circuit breakers e rate limit em uma comunicação serviço-a-serviço. Por exemplo, um serviço que está sob grande carga pode ter sua taxa limitada e assim algumas respostas ainda são processadas, sem causar um colapso no serviço.

Outras estratégias para mitigar falhas incluem o uso de bibliotecas RPC (ex. Hystrix) ou contar com um gerenciador de contêineres. Um gerenciador de contêineres como o Kubernetes, Apache Mesos ou Docker Swarm suporta health checking, auto scaling, e roteamento dinâmico nos serviços que não respondem ao health check.

Estas estratégias de mitigação são mais efetivas quando são configuradas apropriadamente para um serviço específico. Por exemplo, serviços diferentes podem controlar volumes diferentes de requisições, precisando de taxas de limites diferentes. Como políticas com limitação de taxa são configuradas? A Netflix tem implementado alguns algoritmos de automação de configuração para configurar estes valores. Outras abordagens seriam expor estas capacidades aos autores dos serviços, que podem configurar os serviços corretamente.

Observabilidade

As falhas são inevitáveis. Implementar a observabilidade -- spanning monitoring, alerta/visualização, rastreamento distribuído, e gravação de logs -- é crítico para minimizar o tempo de resposta de uma falha.

Um service mesh coleta métricas detalhadas da comunicação serviço-a-serviço automaticamente, incluindo a taxa de transferência de dados, latência e disponibilidade. Além do mais, frameworks de service mesh podem injetar cabeçalhos necessários para suportar rastreamento distribuído. Note que estes cabeçalhos ainda precisam ser propagados pelo próprio serviço.

Outras abordagens para coletar métricas similares incluem o uso de agentes de monitoração, coleta de métricas via statsd, e implementar o rastreamento através de bibliotecas (ex., As bibliotecas de instrumentação Jaeger).

Um componente importante da observabilidade é expor aos autores alertas e visualizações. Coletar métricas é apenas o primeiro passo, pensar em como os autores dos serviços criarão alertas e visualizações que são apropriadas ao serviço é importante para fechar o ciclo de observabilidade.

Uma questão de workflow

As mecânicas de implantação de um framework service mesh são diretas. Porém, como a discussão acima deixa claro, a aplicação de um framework service mesh ao seu fluxo de trabalho é mais complicada. A chave para adotar o service mesh é reconhecer que isto impacta os processos de desenvolvimento, e deve estar preparado para investir em integrar a malha de serviços nestes processos. Não existe uma forma de integrar o service mesh nos processos, e as melhores práticas ainda estão emergindo.

Sobre o Autor

Richard Li é o CEO/co-fundador da Datawire, que constrói ferramentas open source para desenvolvedores em Kubernetes. Anteriormente, Richard foi VP Product / Strategy na Duo Security e também foi VP Strategy / Corporate Development na Rapid7. Richard é formado em engenharia mecânica pelo MIT.

Avalie esse artigo

Relevância
Estilo/Redação

Conteúdo educacional

BT