Eu tenho lido muito sobre arquiteturas de microsserviço para aplicativos de servidor e me pergunto como o uso da rede interna não é um gargalo ou uma desvantagem significativa em comparação a uma arquitetura monolítica.
Por uma questão de precisão, aqui estão minhas interpretações dos dois termos:
Arquitetura monolítica: um aplicativo em um único idioma que lida com todas as funcionalidades, dados etc. Um balanceador de carga distribui solicitações do usuário final em várias máquinas, cada uma executando uma instância de nosso aplicativo.
Arquitetura de microsserviço : Muitos aplicativos (microsserviços) lidam com uma pequena parte da funcionalidade e dos dados. Cada microsserviço expõe uma API comum que é acessada através da rede (em oposição à comunicação entre processos ou memória compartilhada na mesma máquina). As chamadas de API são fixadas principalmente no servidor para produzir uma página, embora talvez parte desse trabalho seja feito pelo cliente consultando microsserviços individuais.
Para minha imaginação ingênua, parece que uma arquitetura de microsserviços usa tráfego de rede lento em vez de recursos mais rápidos na mesma máquina (a memória e o disco). Como garantir que a consulta da API pela rede interna não diminua o tempo de resposta geral?
fonte
Respostas:
As redes internas costumam usar conexões de 1 Gbps ou mais rápidas. As conexões de fibra óptica ou ligação permitem larguras de banda muito maiores entre os servidores. Agora imagine o tamanho médio de uma resposta JSON de uma API. Quanto dessas respostas pode ser transmitida por uma conexão de 1 Gbps em um segundo?
Vamos realmente fazer as contas. 1 Gbps é 131 072 KB por segundo. Se uma resposta JSON média for de 5 KB (o que é bastante!), Você poderá enviar 26 214 respostas por segundo através do cabo com apenas um par de máquinas . Não é tão ruim, não é?
É por isso que a conexão de rede geralmente não é o gargalo.
Outro aspecto dos microsserviços é que você pode dimensionar facilmente. Imagine dois servidores, um hospedando a API e outro consumindo-a. Se alguma vez a conexão se tornar um gargalo, basta adicionar dois outros servidores e você poderá dobrar o desempenho.
É quando nossas 26 214 respostas anteriores por segundo se tornam muito pequenas para a escala do aplicativo. Você adiciona outros nove pares e agora pode servir 262 140 respostas.
Mas vamos voltar ao nosso par de servidores e fazer algumas comparações.
Se uma consulta média não armazenada em cache em um banco de dados demorar 10 ms., Você estará limitado a 100 consultas por segundo. 100 consultas. 26 214 respostas. Atingir a velocidade de 26 214 respostas por segundo requer uma grande quantidade de cache e otimização (se a resposta realmente precisar fazer algo útil, como consultar um banco de dados; as respostas no estilo "Hello World" não se qualificam).
No meu computador, no momento, o DOMContentLoaded para a página inicial do Google teve 394 ms. depois que a solicitação foi enviada. Isso é menos de 3 solicitações por segundo. Para a página inicial do Programmers.SE, ocorreram 603 ms. depois que a solicitação foi enviada. Isso não é nem 2 solicitações por segundo. A propósito, eu tenho uma conexão de internet de 100 Mbps e um computador rápido: muitos usuários esperam mais.
Se o gargalo for a velocidade da rede entre os servidores, esses dois sites poderão literalmente fazer milhares de chamadas para APIs diferentes enquanto veiculam a página.
Esses dois casos mostram que a rede provavelmente não será o seu gargalo na teoria (na prática, você deve fazer os benchmarks e os perfis reais para determinar a localização exata do gargalo do seu sistema específico hospedado em um hardware específico). O tempo gasto realizando o trabalho real (seria consultas SQL, compactação, qualquer que seja) e enviando o resultado ao usuário final é muito mais importante.
Pense em bancos de dados
Geralmente, os bancos de dados são hospedados separadamente do aplicativo Web que os utiliza. Isso pode suscitar uma preocupação: e a velocidade da conexão entre o servidor que hospeda o aplicativo e o servidor que hospeda o banco de dados?
Parece que há casos em que a velocidade da conexão se torna problemática, ou seja, quando você armazena grandes quantidades de dados que não precisam ser processados pelo próprio banco de dados e devem estar disponíveis agora (ou seja, arquivos binários grandes). Mas tais situações são raras: na maioria dos casos, a velocidade de transferência não é tão grande em comparação com a velocidade de processamento da própria consulta.
Quando a velocidade de transferência realmente importa é quando uma empresa está hospedando grandes conjuntos de dados em um NAS, e o NAS é acessado por vários clientes ao mesmo tempo. É aqui que uma SAN pode ser uma solução. Dito isto, esta não é a única solução. Os cabos Cat 6 podem suportar velocidades de até 10 Gbps; A ligação também pode ser usada para aumentar a velocidade sem alterar os cabos ou os adaptadores de rede. Existem outras soluções, envolvendo replicação de dados em vários NAS.
Esqueça a velocidade; pense em escalabilidade
Um ponto importante de um aplicativo Web é poder escalar. Embora os desempenhos reais sejam importantes (porque ninguém quer pagar por servidores mais poderosos), a escalabilidade é muito mais importante, porque permite que você jogue hardware adicional quando necessário.
Se você tiver um aplicativo não particularmente rápido, perderá dinheiro porque precisará de servidores mais poderosos.
Se você tiver um aplicativo rápido que não pode ser dimensionado, perderá clientes porque não poderá responder a uma demanda crescente.
Da mesma forma, as máquinas virtuais foram vistas há uma década como um enorme problema de desempenho. De fato, hospedar um aplicativo em um servidor versus hospedá-lo em uma máquina virtual teve um impacto importante no desempenho. Embora a diferença seja muito menor hoje, ela ainda existe.
Apesar dessa perda de desempenho, os ambientes virtuais se tornaram muito populares devido à flexibilidade que oferecem.
Assim como na velocidade da rede, você pode achar que a VM é o gargalo real e, dada a sua escala real, você economizará bilhões de dólares hospedando seu aplicativo diretamente, sem as VMs. Mas não é isso que acontece em 99,9% dos aplicativos: o gargalo deles está em outro lugar, e a desvantagem de uma perda de alguns microssegundos por causa da VM é facilmente compensada pelos benefícios da abstração e escalabilidade de hardware.
fonte
Eu acho que você está lendo muito na parte 'micro'. Isso não significa substituir todas as classes por um serviço de rede, mas componente um aplicativo monolítico em componentes de tamanho sensato, cada um lidando com um aspecto do seu programa. Os serviços não se comunicam, portanto, na pior das hipóteses, você dividiu uma solicitação de rede grande em várias menores. Os dados retornados não serão significativamente diferentes dos que você recebe (embora você possa retornar mais dados e consolidá-los no cliente)
fonte
Estruturando o acesso ao código e aos recursos, de forma que o sistema resultante possa ser flexível o suficiente para ser executado como um aplicativo monolítico ou um aplicativo distribuído via configuração. Se você abstrair o mecanismo de comunicação por trás de alguma interface comum e criar seu sistema com a simultaneidade em mente, poderá otimizar tudo facilmente depois de criar um perfil do sistema e encontrar os gargalos reais da garrafa.
fonte
Gostaria de adicionar uma perspectiva diferente, de um setor diferente, com suposições muito diferentes - simulação distribuída (no nível da entidade). Conceitualmente, isso é muito parecido com um videogame FPS distribuído. Principais diferenças: todos os jogadores compartilham algum estado: onde o dragão está agora; nenhuma chamada ao banco de dados; tudo é mantido na RAM para velocidade e baixa latência, o rendimento é menos relevante (mas acho que você também não pode ignorá-lo).
Você pode pensar em cada aplicativo participante como um monólito (que representa todas as facetas de um jogador) ou como um microsserviço (que representa apenas um único jogador na multidão).
Meus colegas têm demonstrado interesse em dividir um único aplicativo participante, ainda mais em microsserviços menores que podem ser compartilhados, por exemplo, arbitragem de danos ou cálculos de linha de visão, coisas que geralmente são agrupadas nas simulações.
O problema é a latência do envio de chamadas e a espera de solicitações. A largura de banda é irrelevante e abundante de qualquer maneira, como outros já apontaram. Mas se um cálculo de linha de visão passar de 1 microseg a 100 microseg (por exemplo, devido ao enfileiramento no novo microsserviço compartilhado entre todos os aplicativos do player), será uma perda enorme (pode ser necessário vários ou muitos cálculos de linha de visão para cada atualização, várias atualizações / segundo).
Pense com muito cuidado sobre como os serviços funcionam, quando são chamados e quais dados são trocados. Nossos aplicativos já não trocam apenas informações de posição, eles trocam informações de acerto de contas - estou na posição x, seguindo na direção y na velocidade q. E não preciso atualizar minhas informações até que essas suposições mudem. Muito menos atualizações e latência (embora ainda sejam um problema) surgem proporcionalmente com menos frequência.
Portanto, em vez de solicitar um serviço em uma granulação fina com uma frequência mais alta, tente diminuir a frequência:
Agora lembre-se de verificar suas suposições sobre o seu sistema. Se você está mais preocupado com a taxa de transferência do que com a latência, ou se não possui estado compartilhado etc., use todos os meios de microsserviços onde eles fizerem sentido. Só estou dizendo que talvez não as use onde não fazem sentido.
fonte
Sua imaginação ingênua está certa. E muitas vezes isso não importa. Máquinas modernas são rápidas. As principais vantagens da arquitetura de microsserviço são vistas no esforço e no tempo de desenvolvimento e manutenção.
E, é claro, não há regra dizendo que você não pode usar memória compartilhada ou mesmo implantar fisicamente vários serviços em um executável. Desde que você o projete, não será dependente disso.
fonte
Como muitas pessoas mencionaram, não se trata de gargalos na rede. É mais sobre fragilidade da rede. Portanto, o primeiro passo é evitar a comunicação síncrona. É mais fácil do que parece. Tudo que você precisa é de serviços com limites corretos. Os limites certos resultam em serviços autônomos, pouco acoplados e altamente coesos. Um bom serviço não precisa de informações de outro serviço, ele já possui. A única maneira pela qual bons serviços se comunicam é através de eventos. Os bons serviços também são consistentes, portanto, não há transações distribuídas.
A maneira de alcançar essa bondade é identificar primeiro os recursos de negócios. A capacidade comercial é uma responsabilidade comercial específica. Alguma contribuição para o valor geral dos negócios. Então, aqui está a minha sequência de etapas que eu tomo quando penso nos limites do sistema:
Lembre-se de que o serviço comercial inclui pessoas, aplicativos, processos comerciais. Normalmente, apenas uma parte é representada como autoridade técnica.
Isso pode parecer um pouco abstrato, portanto, provavelmente um exemplo de identificação de limites de serviço seria de algum interesse.
fonte
Apenas outro fator a ser adicionado às respostas atuais. Com serviços de granulação grossa . Você deseja evitar a latência de todas as chamadas; portanto, em vez de fazer 10 chamadas, você faz uma chamada que obtém 10 partes de dados necessárias em um DTO.
E lembre-se de que os microsserviços não são tão micro quanto as pessoas pensam.
fonte