Quais são os possíveis problemas com a dependência circular operacional entre microsserviços

5

Sou relativamente novo na arquitetura de microsserviço e nunca participei de um projeto em que o arquiteto insista em ter uma dependência circular entre serviços.

Eu estou em uma posição sem a opção de projetar dois microservices com dependência circular. É minha reação natural contra fazê-lo - um real, ou estou simplesmente transferindo incorretamente de outras áreas do desenvolvimento de software?

Um problema óbvio que eu posso ver é com o bootstrapping, forçando os serviços a continuarem se conectando uns aos outros, sendo impossível criar uma ordem em que todas as dependências já estejam funcionando. No entanto, isso não parece tão ruim, já que tenho que ter isso de qualquer maneira para tolerância a falhas.

Também cria alguns problemas com testes, mas parece que poderei resolvê-los com duplas.

Quais riscos e perigos reais existem nessa arquitetura (se houver) que eu preciso considerar?

    
por gsf 04.06.2017 / 23:42
fonte

2 respostas

6

Em outra resposta , eu não recomendo isso.

A questão principal que posso ver, além do problema de bootstrap que está relacionado, é se um dos serviços no ciclo falhar, então todos eles falharão. É bastante ruim depurar / restaurar o serviço quando um serviço falha porque um de seus serviços upstream falhou. Nesse caso, você pode voltar atrás nas dependências até descobrir qual é a dependência upstream mais próxima que ainda está funcionando. Você pode corrigir essa dependência e, em seguida, repita o processo se o serviço original ainda não estiver funcionando. Nesse caso, você isolou o segundo serviço com falha para ser downstream do que você acabou de corrigir. Continue repetindo até que o serviço original esteja funcionando.

Se você tiver dependências cíclicas, não há como saber qual serviço no ciclo está causando o problema. Se dois ou mais serviços estão tendo problemas, então você está em uma situação de luzes de Natal / série: se dois serviços falharam, mas você não sabe qual, então você não recebe nenhuma informação se "consertar" um realmente ajudou. Somente quando você consertar ambos os serviços em falha, você saberá quais eram. Se o problema for operacional e puder ser resolvido reiniciando o serviço, a coisa mais rápida a ser feita para restaurar o serviço é, provavelmente, reiniciar o ciclo inteiro. Isso evita a necessidade de isolar o problema e trata efetivamente o ciclo como um único serviço, pelo menos de uma perspectiva de gerenciamento de falhas. Se o problema é um defeito de software, então você está em uma posição muito pior porque para corrigir o problema é necessário isolar o defeito, e é isso que as dependências cíclicas dificultam. Obviamente, um bom monitoramento / registro ajuda significativamente com isso. Da mesma forma que obviamente, quanto menor o ciclo, menos grave é esse problema.

    
por 05.06.2017 / 03:48
fonte
0

Não sei exatamente o que você quer dizer com uma dependência circular, mas em um nível geral dois micro-serviços devem poder ser implantados, gerenciados e versionados de maneira interdependente um do outro. Se você está em uma posição onde uma mudança no micro-serviço A resulta em uma mudança no micro-serviço B, então você está meio que fazendo errado. Mas eu posso ver onde dois serviços podem ter inter-dependências.

Mas é possível ter dependências "circulares" e ainda ser um micro-serviço razoável. Digamos, por exemplo, um serviço gerencia usuários e credenciais e o outro gerencia sessões de login. Para alterar as credenciais de um usuário, você pode precisar de um token de sessão válido que prove que você é o mesmo usuário. Para obter um token de sessão, você precisa poder autenticar um usuário com suas credenciais. Os dois serviços precisam estar prontos para que a segurança funcione, mas eles podem ter interfaces claramente definidas. Para testes, você pode criar uma versão stub do outro serviço.

A API do serviço de credenciais pode permitir que um usuário valide credenciais, registre usuários e obtenha detalhes para um usuário. O serviço de sessão tem uma API que retorna um token de sessão, recebe um conjunto de credenciais e retorna o principal para um determinado token de sessão. Se as definições da API forem bem pensadas e cuidadosamente seguidas, acho que seria ótimo ter essas interdependências. Mas se você não pode estabelecer contratos claros, e as mudanças em um serviço implicam em mudar o outro, então você provavelmente não deveria ter dividido os serviços.

Como parte do micro-serviço em algo tão crítico quanto a autenticação do usuário, você colocaria um balanceador de carga na frente de um cluster de contêineres ou VMs executando o serviço. Dessa forma, você poderia executar duas ou três cópias de cada serviço e, se uma delas fosse desativada, o balanceador de carga ocultaria isso. (Além de políticas de repetição razoáveis para falhas transitórias, etc.). Mas você não seria capaz de autenticar a menos que o serviço de credenciais do usuário estivesse disponível e o serviço da sessão também estivesse disponível.

Adicionando um pouco de esclarecimento:

Em geral (micro-serviços, dependências de classe, etc.), você quer que seu acoplamento seja um gráfico acíclico direcionado. B depende de A, então A não deve ter conhecimento de B. Este não é um princípio específico de micro-serviço, mas um princípio geral de design. Uma maneira de corrigir meu design acima é dividir a validação da credencial em um serviço separado e recuperar o DAG. O risco específico que você está tentando evitar é que você não pode mudar ou evoluir A e B independentemente uns dos outros. Você sempre acabará fazendo alterações em ambos.

Nunca é uma palavra muito strong, então eu não diria que você nunca deve fazer algo, mas você deve evitar dependências circulares. Eu acho que o acoplamento é o perigo real.

    
por 05.06.2017 / 00:21
fonte