Microsserviço 1
Microsserviços são serviços que podem ser lançados de forma independente e são modelados com base e um domínio de negócio.
A arquitetura de microsserviços é um tipo de arquitetura orientada a serviços, com fronteiras dos serviços bem definidas, além de ser independente de tecnologia. Ter fronteiras de serviços claras e estáveis resulta em sistemas com baixo acoplamento e alta coesão.
Do ponto de vista externo, um microsserviço é uma caixa-preta, já que os detalhes de implementação permanecem totalmente ocultos. Por isso, microsserviços evitam compartilhamento de bancos de dados; em vez disso, cada microsserviços encapsula do seu próprio banco de dados quando for necessário. Claro que compartilhar bancos de dados não é necessariamente um problema, apenas deve ser evitado. Cada caso deve ser analisado.
Os microsserviços adotam o conceito de ocultação de informações, ou seja, a ideia é ocultar o máximo possível e expor o mínimo possível. Mudanças dentro das fronteiras de um microsserviço não deve afetar um consumidor upstream, o que permite lançar uma funcionalidade de forma independente.
Conceitos essenciais dos microsserviços:
Ideias essenciais para compreensão dos microsserviços:
- implantações independentes: alterar, implantar e disponibilizar a alteração aos usuários não deve envolver a implantação de outros microsserviços. Devemos garantir que os serviços tenham baixo acoplamento e interfaces estáveis.
- modelagem com base em um domínio de negócio: alta coesão nas funcionalidades de negócio, ou seja, basear o desenho do serviço em um domínio de negócio, facilitando o lançamento de novas funcionalidades, permitindo recombinar os serviços de maneiras distintas.
- responsáveis pelo próprio estado: evitar o uso de bancos de dados compartilhados. Se um microsserviço precisa de dados mantidos por outro microsserviço, ele deve solicitar os dados ao segundo microsserviço. Isso dá a capacidade ao segundo microsserviço de decidir o que será compartilhado e o que ficará oculto. Alterações em microsserviços que causem incompatibilidade com versões anteriores devem ser limitadas.
- tamanho: um microsserviço deve ter um tamanho que permita ser facilmente compreendido. Entretanto, tamanho não deve ser algo com que se preocupar. Dois pontos importantes são com quantos microsserviços você é capaz de lidar? e como definir fronteiras para os microsserviços de modo a tirar o máximo proveito deles, sem que tudo se transforme em uma grande confusão com alto grau de acoplamento?
- flexibilidade: a flexibilidade como resultado, presente e vários eixos - organizacional, técnico, de escala, de robustez - pode ser extremamente atraente. Pense como um botão a ser girado. À medida que girar o botão e houver mais microsserviços, maior será a flexibilidade, mas também maior serão as dificuldades.
- alinhamento entre arquitetura e organização: a arquitetura reflete a estrutura da organização. Segundo a lei de Conway, "As organizações que projetam sistemas...estão limitadas a produzir designs que são cópias das estruturas de comunicação dessas organizações." Por isso, arquitetura de três camandas é um bom exemplo dessa lei em ação. Com microsserviço, saímos de sistemas onde cada equipe é responsável por uma camada do sistema para equipes responsáveis por todo o contexto de negócio que o sistema abrange, ponta a ponta.
Sistema monolítico
Sistemas monolíticos faz referência a uma unidade de implantação, todas as funcionalidades são implantadas em conjunto. Podemos dividi-los em:
- sistema monolítico como um único processo: todo o código é implantado como um único processo. Pode fazer sentido para muitas empresas, principalmente empresas menores.
- sistema monolítico modular: um processo único que é composto de módulos separados. Podemos trabalhar em cada módulo de forma independente, mas tudo precisa ser combinado para a implantação. Essa é uma excelente opção para muitas empresas, pois tem uma topologia de implantação mais simples. O desafio fica no banco de dados, já que não passa pela mesma decomposição que existe a nível de código.
- sistema monolítico distribuído: sistema composto de vários serviços, mas, por algum motivo, o sistema como um todo deve ser implantado em conjunto. O ponto é que nessa abordagem, temos as desvantagens de um sistema distribuído e as desvantagens de um sistema monolítico como um único processo. Arquitetura altamente acoplada fazendo com que alterações aparentemente inocentes, que pareciam ser locais quanto ao escopo, acabam causando falhas em outras partes do sistema.
Assim, na minha opinião, a abordagem monolito modular acaba sendo uma excelente opção.
Considerando a simplicidade que a arquitetura monolítica entrega, fluxos de trabalho mais simples, facilidade nas atividades de monitoração, resolução de problemas, teste fim a fim, acaba sendo uma opção válida e, na minha opinião, poderia ser a opção default mais sentata quanto ao estilo de arquitetura, principalmente em escopos de negócio nebulosos.
Tecnologias que viabilizaram os microsserviços
Não devemos sair adotando uma série de tecnologias novas quando iniciamos a adoção de microsserviços. Em vez disso, à medida que a arquitetura de microsserviços for crescendo e os problemas causados por esse crescimento forem surgindo, devemos procurar as tecnologias que possam ajudar e apoiar na resolução destes problemas. Todavia, conhecer as ferramentas disponíveis que ajudam a tirar o máximo proveito da abordagem de microsserviços é parte essencial para uma implementação de sucesso. Tecnologias que tornam os microsserviços viáveis são:
- agregação de logs e tracing distribuído: podemos dizer que é um pré-requisito para a adoção de microsserviço. Essas ferramentas serão ainda mais úteis com a utilização de ids de correlação, em que um id único é usado para um conjunto relacionado de chamadas de serviços. Ferramentas de tracing ajudam a explorar melhor o que o serviço faz, detectar gargalos, fornecer uma visilidade de toda a cadeia de chamadas do serviço.
Jaeger
é um exemplo de ferramenta open source que permite essa rastreabilidade. Para agregação de logs,elasticsearch
+kibana
acabam entregando uma solução em interessante. - containers e Kubernetes: o ideal é que cada instância de execução do microsserviço deva ser isolada. O
docker
consegue entregar esse requisito com maestria. Para administrar vários contêineres distribuídos em várias máquias subjacentes,Kubernetes
consegue apoiar nessa orquestração. Entretanto, não se sinta pressionado a adotar rapidamente essas tecnologias. Claro que oferecem grandes vantagens, mas pode ser bem difícil de justificar o uso considerando um contexto com poucos microsserviços. Quando administrar as implantações começar a se tornar uma dor de cabeça, considere a conteinerização dos serviços e o uso de Kubernetes. - streaming: como os dados podem estar distribuídos em várias bases de dados, trabalhar com stream de dados acaba sendo um abordagem bem presente. O
Kafka
é um protagonista bem presente em um ambiente de microsserviços. Mas também é uma tecnologia que será utilizada pela necessidade de resolver um problema, não como um pré-requisito. - nuvem pública e produtos serverless: aumentando a adoção da arquitetura de microsserviços, também aumentam as demandas na área operacional. Serviços gerenciados oferecidos pelas núvens públicas são uma ótima opção para transferir essa alta demanda operacional.
Vantagens dos microsserviços
As vantagens são muitas e variadas, mas muitas dessas vantagens podem ser atribuídas a qualquer sistema distribuído:
- heterogeneidade de tecnologias: podemos empregar diferentes tecnologias em cada microsserviço. Se o desempenho uma parte do sistema precisa ser melhorada, podemos empregar a tecnologia que melhor atenda a necessidade. Claro que adotar várias tecnologias não deixa de ter um custo adicional.
- robustez: caso um componente o ecossistema falhe, desde que essa falha não seja em cascata, o problema pode ser isolado, e o resto do sistema continuará funcionando. Isso difere bem dos monolíticos, já que se o serviço falhar, tudo para de funcionar. Com microsserviços, podemos criar sistemas que saibam lidar com a falha total de alguns serviços. Devemos conhecer os novos motivos de falhas que sistemas distribuídos têm que lidar. As redes podem e vão falhar, assim como as máquinas.
- escalabilidade: em um monolítico, caso uma pequena parte precise escalar, todo o sistema terá de escalar junto. Com serviços menores, podemos escalar apenas os serviços que precisam ser escalados.
- facilidade de implantação: podemos fazer uma alteração em um único serviço e implantá-lo independentemente do resto do sistema. Em caso de problema, esse serviço pode ser isolado e um rollback feito com mais facilidade.
- alinhamento organizacional: equipes menores trabalhando em base de código menor tendem a ser mais produtivas. Podemos criar a relação ideal entre tamanho de equipe e produtividade.
- composição: reutilização de funcionalidades, consumidas de diferentes maneiras com diferentes propósitos.
Complexidade dos microsserviços
Como todo sistema distribuídos, temos grandes vantagens, mas também temos diversas complexidades e desafios:
- experiência dos desenvolvedores: runtimes que exigem muito recurso para serem executados pode dificultar a execução na máquina do desenvolvedor. Mesmo com runtimes menos exigentes, há um limite para a quantidade de componentes que podem ser executados localmente. Complica ainda mais se estiver usando serviços em nuvem que não podem ser executados localmente.
- sobrecarga tecnológica: a própria quantidade de tecnologias que surgiram para permitir a adoção de microsserviços pode ser opressivo. Podemos desenvolver microsserviços em diferentes linguagens, utilizar diferentes bancos de dados, mas tudo isso são opções, não requisitos. Entender problemas de consistência de dados, latência, modelagem de serviços, etc, exigirão um entendimento mais profundo. À medida que a complexidade da arquitetura de microsserviços crescer, novas tecnologias poderão ser introduzidas conforme forem necessárias. Crescimento gradual.
- custos: no curto prazo, os custos irão aumentar, já que existirão mais itens em execução. Além disso, conhecer novas ideias e descobrir como usar com eficácia exige tempo. Com isso, haverá maior lentidão na entrega de novas funcionalidades.
- relatórios: agora os dados estão separados em vários esquemas isolados do ponto de vista lógico. Uma alternativa poderia ser publicar os dados dos microsserviços em um banco de dados centralizado para relatórios.
- monitoração e resolução de problemas: rastreabilidade do impacto caso apenas uma única instância de um serviço ficar inativa, já que teremos várias instâncias de vários serviços para monitorar.
- segurança: mais dados fluindo entre os serviços através da rede podem ser observados, deixando mais vulnerável a ataques man-in-the-middle.
- testes: escopo de testes end to end se torna mais amplo, já que teremos diversos serviços que devem estar configurados de forma apropriada para o cenário de teste. O nível de confiança tende a diminuir. Assim, testes orientados à contrato e técnicas de entrega progressiva precisam ser estudadas.
- latência: informações serializadas de desserializadas entre serviços causam maior latência. Por isso a adoção de microsserviços deve ser feita de forma gradual, até para que fique claro qual a latência aceitável para as operações.
- consistência dos dados: consistência eventual será algo presente, já que vários serviços gerenciam estados em diferentes bancos de dados.
A adoção de microsserviços trás consigo uma avaliação de seus próprios problemas, habilidades, tecnologias e o que se pretende alcançar. Pode não ser uma opção para produtos ou startups extremamente novos já que o domínio de trabalho está suscetível a mudanças significativas. Aguardar uma estabilidade do domínio de trabalho acaba sendo uma atitude sensata.
Agora, microsserviço acaba sendo um abordagem muito interessante quando diferentes desenvolvedores precisam trabalhar com o mesmo produto, sem que um atrapalhe o outro. Um outro usecase interessante são aplicações SAAS.
O uso deve ser justificado pelos problemas que estiver tentando resolver. O pensamento de fazer o simples primeiro acaba funcionando mais facilmente. Quando os conceitos fundamentais são entendidos e compreendidos, a abordagem de microsserviços pode entregar uma arquitetura eficaz e produtiva.