Arquiteturas monolíticas e de microsserviços
A Fabrikam integrou o seu novo serviço de drones na sua aplicação existente. Percebeu que esta solução não é um bom plano a longo prazo para a aplicação. O sistema existente é uma arquitetura monolítica, mas o que é que isso significa exatamente?
O que é uma arquitetura monolítica?
Uma arquitetura monolítica é uma arquitetura em que todos os componentes de uma aplicação são colocados numa única unidade. Normalmente, esta unidade está limitada a uma única instância de runtime da aplicação. As aplicações tradicionais geralmente consistem numa interface Web, numa camada de serviços e numa camada de dados. Numa arquitetura monolítica, estas camadas são combinadas numa instância da aplicação.
As arquiteturas monolíticas são geralmente soluções adequadas para aplicações pequenas, mas podem tornar-se difíceis à medida que a aplicação cresce. O que era originalmente uma pequena aplicação pode rapidamente tornar-se num sistema complexo difícil de dimensionar, difícil de implementar e difícil de inovar.
Todos os serviços estão contidos numa única unidade. Esta organização coloca desafios à medida que aumenta o negócio e a subsequente carga de sistema. Alguns destes desafios são:
- Dificuldade em dimensionar os serviços de forma independente.
- Complexidade no desenvolvimento e gestão de implementações à medida que o código base aumenta, o que atrasa os lançamentos de novas versões e a implementação de novas funcionalidades.
- A arquitetura está ligada a uma única pilha de tecnologia, o que limita a inovação em novas plataformas e SDKs.
- As atualizações dos esquemas de dados podem tornar-se cada vez mais difíceis.
Estes desafios podem ser abordados ao analisar as arquiteturas alternativas, como uma arquitetura de microsserviços.
O que é uma arquitetura de microsserviços?
Uma arquitetura de microsserviços consiste em serviços que são pequenos, independentes e conjugados livremente. Cada serviço pode ser implementado e dimensionado de forma independente.
Um microsserviço é pequeno ao ponto de uma única pequena equipa de programadores conseguir escrevê-lo e tratar da sua manutenção. Uma vez que os serviços podem ser implementados de forma independente, uma equipa pode atualizar um serviço existente sem reconstruir e reimplementar toda a aplicação.
Cada serviço é normalmente responsável pelos seus próprios dados. A estrutura de dados é isolada, pelo que as atualizações ou alterações ao esquema não estão dependentes de outros serviços. Os pedidos de dados são normalmente tratados através de APIs e fornecem um modelo de acesso bem definido e consistente. Os detalhes internos da implementação são ocultados dos consumidores de serviços.
Como cada serviço é independente, podem utilizar diferentes pilhas de tecnologia, estruturas e SDKs. É comum ver os serviços dependerem de chamadas REST para comunicação serviço-a-serviço usando APIs bem definidas em vez de chamadas de procedimento remoto (RPCs) ou outros métodos de comunicação personalizados.
As arquiteturas de microsserviços são tecnologicamente agnósticas, mas verá frequentemente que são utilizados contentores ou tecnologias sem servidor na implementação. A implementação contínua e a integração contínua (CI/CD) são frequentemente utilizadas para aumentar a velocidade e a qualidade das atividades de desenvolvimento.
Benefícios de uma arquitetura de microsserviços
Por que motivo escolheria uma arquitetura de microsserviços? Existem vários benefícios principais para uma arquitetura de microsserviços:
- Agilidade
- Código pequeno, equipas pequenas
- Misto de tecnologias
- Resiliência
- Escalabilidade
- Isolamento de dados
Agilidade
Como os microsserviços são implementados de forma independente, pode gerir a correção de erros e o lançamento de funcionalidades com mais facilidade. Pode atualizar um serviço sem implementar novamente toda a aplicação e reverter uma atualização caso algo corra mal. Em muitas aplicações tradicionais, se for encontrado um erro numa parte da aplicação, esse erro poderá bloquear todo o processo de lançamento da versão. Como resultado, as novas funcionalidades podem ficar a aguardar que uma correção de erro seja integrada, testada e publicada.
Código pequeno, equipas pequenas
Um microsserviço deve ser pequeno ao ponto de ser possível que uma única equipa consiga criá-lo, testá-lo e implementá-lo. As bases de código pequenas são mais fáceis de compreender. Numa aplicação monolítica grande, as dependências de código têm tendência a tornarem-se complicadas ao longo do tempo. A adição de uma nova funcionalidade requer que se mexa no código em muitos pontos. Uma arquitetura de microsserviços minimiza as dependências ao não compartilhar códigos ou armazenamentos de dados. o que permite adicionar novas funcionalidades de forma mais fácil.
Além disso, equipas mais pequenas promovem uma maior agilidade. A “regra das duas pizzas” define que uma equipa deve ser pequena o suficiente para que duas pizzas cheguem para alimentar toda a equipa. Como é óbvio, não se trata de uma métrica exata e depende do apetite dos membros da equipa! Porém, o que interessa reter é que as equipas grandes tendem a ser menos produtivas, porque a comunicação é mais demorada, a despesa de gestão aumenta e a agilidade diminui.
Misto de tecnologias
As equipas podem escolher a tecnologia que melhor se adequa ao seu serviço. Podem utilizar uma combinação de pilhas de tecnologia conforme apropriado. Cada equipa pode desenvolver as tecnologias que dão suporte ao respetivo serviço de forma independente. Por serem independentes, os serviços podem utilizar diferentes linguagens de desenvolvimento, serviços cloud, SDKs e muito mais. As equipas podem escolher as melhores opções para o seu serviço, minimizando qualquer efeito externo sobre os consumidores do serviço.
Resiliência
Se um microsserviço individual ficar indisponível, ele não interromperá todo o aplicativo, desde que todos os microsserviços upstream sejam projetados para lidar com falhas corretamente (por exemplo, implementando circuit breaking). O benefício para seus usuários ou consumidores de serviços é uma experiência sempre ativa para seu aplicativo.
Escalabilidade
Uma arquitetura de microsserviços permite o dimensionamento de cada microsserviço de forma independente dos outros. Pode aumentar horizontalmente subsistemas que necessitem de mais recursos, sem aumentar horizontalmente toda a aplicação. Esta organização melhora o desempenho geral da aplicação. Ajuda também a minimizar os custos. Pode adicionar mais recursos somente aos serviços que precisam deles, em vez de aumentar verticalmente toda a aplicação.
Isolamento de dados
Uma arquitetura de microsserviços melhora a capacidade de efetuar atualizações de esquema de dados porque só é afetado um único microsserviço. Numa aplicação monolítica, as atualizações de esquema podem tornar-se num desafio. Partes diferentes da aplicação podem mexer nos mesmos dados, o que torna arriscada qualquer alteração no esquema. Com uma arquitetura de microsserviços, pode atualizar um esquema, mas manter a superfície da API intacta. Os consumidores do serviço têm a mesma experiência, independentemente da arquitetura de dados subjacente.
Potenciais desafios de uma arquitetura de microsserviços
Há muitos benefícios para uma arquitetura de microsserviços, mas não é uma solução para tudo. Uma arquitetura de microsserviços tem o seu próprio conjunto de desafios:
- Complexidade
- Desenvolvimento e teste
- Falta de governação
- Congestionamento e latência de rede
- Integridade dos dados
- Gestão
- Controlo de Versão
- Competências
Complexidade
Uma aplicação de microsserviços tem mais partes em movimento do que a aplicação monolítica equivalente. Cada serviço é mais simples, mas o sistema como um todo é mais complexo. Com as ferramentas de deteção de serviços, orquestração e automação, pode haver mais partes a gerir na aplicação global.
Desenvolvimento e teste
Escrever um serviço pequeno que dependa de outros serviços dependentes exige uma abordagem diferente da escrita para uma aplicação monolítica ou em camadas tradicional. As ferramentas existentes nem sempre são concebidas para funcionar com as dependências do serviço. Refatorizar através de limites de serviço pode ser difícil. Testar as dependências do serviço também é particularmente desafiante, especialmente quando a aplicação está a evoluir rapidamente.
Falta de governação
A abordagem descentralizada da criação de microsserviços tem vantagens, mas também pode provocar problemas. Pode ficar com tantas linguagens e estruturas diferentes que se torna difícil gerir a aplicação. Poderá ser útil implementar alguns padrões em todo o projeto, sem restringir excessivamente a flexibilidade das equipas. A necessidade de padrões uniformes aplica-se especialmente a funcionalidades transversais, como o registo e as métricas.
Congestionamento e latência de rede
A utilização de muitos serviços pequenos e granulares pode originar uma maior comunicação entre serviços. Se a cadeia de dependências de serviço ficar muito longa, por exemplo, o serviço A chama B, que chama C..., a latência extra dessas chamadas de rede pode se tornar um problema. Conceba as APIs de forma cuidada. Evite APIs excessivamente comunicativas, considere os formatos de serialização e procure locais para utilizar padrões de comunicação assíncrona.
Integridade dos dados
Cada microsserviço é responsável pela sua própria persistência de dados. Como resultado, a consistência dos dados pode ser um desafio. Adote a consistência eventual sempre que possível. Pode também acabar com dados duplicados e uma arquitetura de dados dispersa. Esta situação pode aumentar os custos de armazenamento brutos e os custos do serviço de plataforma de dados com a duplicação de dados e serviços.
Gestão
O êxito dos microsserviços requer uma cultura DevOps madura. O registo correlacionado entre serviços pode ser um desafio. Normalmente, o registo tem de correlacionar múltiplas chamadas de serviço para uma única operação de utilizador.
Controlo de Versão
As atualizações de um serviço não podem interromper os serviços que dependem dele. Múltiplos serviços poderiam ser atualizados num determinado momento. Sem uma estrutura cuidadosa, poderia ter problemas de retrocompatibilidade ou compatibilidade com as versões seguintes. Os serviços que apresentam algum atraso na adoção de novas versões de API podem aumentar os recursos e a manutenção necessários para APIs mais antigas.
Competências
Os microsserviços são sistemas altamente distribuídos. Estes sistemas distribuídos exigem geralmente um conjunto de competências diferente para desenvolver, gerir e manter de forma adequada. Avalie cuidadosamente se a equipa tem as competências e a experiência para o êxito. Permita o tempo e o planeamento de que as suas equipas vão precisar para desenvolver as suas capacidades.
Quando deve escolher uma arquitetura de microsserviços?
Com base nestas informações gerais, em que situações uma arquitetura de microsserviços é mais adequada?
- Aplicações grandes que requerem uma maior velocidade de lançamento.
- Aplicações complexas que precisam de ser altamente dimensionáveis.
- Aplicações com domínios avançados ou muitos subdomínios.
- Uma organização que consiste de pequenas equipas de desenvolvimento.