Microsserviços em estágio avançado
Li sobre o esforço da equipe do Amazon Prime Video para escalar e cortar custos em 90% combinando seus microsserviços em um monólito. Embora eu tenha certeza de que há mais na história aqui, há histórias semelhantes publicadas na Internet; uma espécie de refutação à mania dos microsserviços da última década.
Isso me lembrou dos últimos anos que passei no Twitter, onde o número de microsserviços (na casa dos milhares) atingiu o pico e depois começou a cair, mesmo com o aumento do tráfego. Todos os tipos de lógica de aplicativo foram absorvidos em plataformas gerenciadas monolíticas de um tipo ou outro. O princípio de criar microsserviços específicos não é intrinsecamente bom e, depois de certo ponto, também não parecia ser um ROI positivo para muitas de nossas equipes.
Uma arquitetura de microsserviço pode ser cara. Houve uma narrativa na última década de que esta é uma política natural para grandes organizações de engenharia, porque:
- As equipes podem iterar em seus serviços com autonomia da organização mais ampla e seu código
- Pequenos componentes da arquitetura de serviço podem ser modificados sem interromper o sistema maior
- A arquitetura permite a definição de aplicativos claros e gerenciáveis e domínios de falha por meio de serviços independentes
- A arquitetura permite cargas de trabalho independentemente ajustáveis ou escaláveis
É preciso levar em conta a complexidade do trabalho que é transferido para pequenas equipes proprietárias de serviços e, como resultado, para o ecossistema mais amplo - em contraste com um número singular ou pequeno de monólitos. O trabalho transferido depende da maturidade da pilha de tecnologia da organização; mas pode incluir:
Responsabilidades operacionais distribuídas e despesas gerais entre todas as equipes proprietárias de serviços
- A compreensão e configuração dos componentes de infraestrutura de serviço de agendamento de trabalho e ferramentas de implantação, descoberta de serviço, estruturas RPC, VMs e ajuste associado, monitoramento de serviço e registro
- Definições distribuídas e processos de desenvolvimento para SLOs e SLIs, falha de serviço e tratamento de falhas, tratamento de contrapressão e sinalização de erro
- Planejamento de capacidade distribuído e frequentemente descoordenado, teste de carga, implementação de teste de integração e responsabilidades
- A lógica do aplicativo que interage com muitos serviços de back-end geralmente navega em uma série de definições de API de serviço sob medida, semântica, modelos de dados, sistemas de controle de versão e, ocasionalmente, até mesmo protocolos diferentes
- Os engenheiros devem entender e raciocinar sobre a arquitetura geral do serviço e os padrões de tráfego para criar coisas funcionais
- Soluções alternativas orgânicas para caminhos de serviço abaixo do ideal ou com gargalos, replicação e consumo de dados distribuídos, dependências de solicitação circular
- Abordagens localizadas para problemas de inferência e classificação, processamento de eventos, tradução de API de protocolo HTTP/interno e mapeamento de modelo de dados
- Fragmentação geral e dificuldade em manter os padrões na pilha
O problema é que o processo de criação, construção e operacionalização de um novo serviço é caro . A integração desse serviço na arquitetura de serviço de produção é difícil. A atenção necessária para ajustar outro serviço para operação eficiente; para configurar contas de serviço correspondentes, perfis de observabilidade e registro, testes de integração, rotação de plantão e tudo mais apenas aumenta a manutenção e a sobrecarga operacional da equipe. A maioria das organizações carece de automação e andaimes de ponta a ponta para esse tipo de trabalho clichê complexo.
Essa sobrecarga é um grande desincentivo para as equipes seguirem o princípio de arquitetura de microsserviço inspirado no UNIX de “ fazer uma coisa bem ”. É mais fácil criar novos casos de uso em serviços existentes. Na extremidade mais distante do espectro, as equipes operam serviços “macro” que começam a encapsular tudo pelo que são responsáveis como uma equipe, o que pode incluir uma variedade de produtos ou recursos. A qualidade da propriedade cai com o tempo, porque as reorganizações são uma ocorrência relativamente comum. Você está trabalhando com uma bola de lama.
As interrupções de serviço de macro não se limitam a um conjunto de recursos específico, mas sim a uma faixa imprevisível ou sem princípios do sistema, que pode se assemelhar a organogramas históricos. O site pode ou não tolerar a indisponibilidade desses serviços. É mais difícil otimizar serviços para cargas de trabalho heterogêneas; caminhos de chamada não podem ser desembaraçados. Um ex-colega cunhou isso como “o micrólito”.
Os microsserviços codificam e incentivam a otimização local na arquitetura de serviço. É difícil responsabilizar as equipes por um design baseado em princípios para servir a arquitetura quando o objetivo é a federação de desenvolvimento de serviço. Da mesma forma, é difícil resolver problemas de otimização em todo o back-end quando as propriedades dos serviços dependentes são personalizadas. Sem arquitetura de serviço cuidadosamente projetada e plataformas de serviço de suporte, é difícil encontrar alavancagem — código de plataforma de produto reutilizável está espalhado por uma série de serviços grandes ou bibliotecas compartilhadas ; os serviços frontend geralmente sob medida.
A alavancagem do microsserviço foi encontrada na camada de computação (o que quer que esteja orquestrando e executando tarefas ou contêineres de serviço), descoberta de serviço, VM (aplicável em determinados contextos), estrutura de serviço (como gRPC , Finagle ou Rest.Li ) e ferramentas de desenvolvedor centralizadas . É claro que as malhas de serviço encapsulam bem algumas dessas preocupações.
Outra maneira de abordar esses problemas é reduzir a sobrecarga funcional. Portanto, em vez de tentar reduzir a sobrecarga repetida de infraestrutura da execução do serviço , você pode reduzir os custos das equipes que reimplementam classes de trabalho comuns . É por isso que as plataformas gerenciadas são tão bem-sucedidas — mesmo que a criação ou operação de um serviço seja cara, se pudermos reduzir sua lógica de aplicativo terceirizando para uma plataforma gerenciada pública ou privada, isso se tornará um fardo menor para a equipe proprietária.
É importante que as organizações avaliem cuidadosamente as compensações arquitetônicas com base em suas necessidades específicas, metas e maturidade da pilha de tecnologia. Os microsserviços fornecem certas vantagens. Eles também introduzem complexidades e sobrecarga operacional que parecem administráveis no início, mas aumentam com o tempo. A falha em resolver esses problemas torna o processo de desenvolvimento de ponta a ponta um pouco mais fácil do que trabalhar em um monólito.
Algumas coisas a serem lembradas, especialmente se você estiver trabalhando com um micrólito herdado:
- “Grandes serviços” ou monólitos não são necessariamente ruins; eles exigem um tipo diferente de ferramentas, suporte de infra e conjunto de princípios dos microsserviços, mas devem ser construídos para capturar elementos comuns bem definidos da arquitetura de serviço
- Defender o princípio de “uma tarefa, um serviço” tende a ser muito menos prático do que traçar limites intuitivos em torno de áreas de estreita colaboração, preocupações com o desempenho e domínios distintos de falha – e pressionar as equipes a seguir o plano
- Você pode aliviar as complexidades e a sobrecarga de “muitos serviços” reduzindo a profundidade vertical da pilha pelos quais os proprietários de serviços são responsáveis (estruturas de serviço, malha de serviço, computação), bem como a extensão do espaço do aplicativo por meio de serviços gerenciados ou plataformas para fluxos de trabalho comuns