Os microsserviços devem conversar entre si?

30

Estou projetando um aplicativo usando microsserviços e não tenho certeza do melhor mecanismo a ser usado para coletar dados de vários serviços.

Eu acredito que existem duas opções:

  • Integre um mecanismo de comunicação entre serviços que permita que os serviços conversem diretamente. O API Gateway chama um serviço individual, que chama outros serviços para coletar dados, antes de retornar a resposta consolidada ao API Gateway. A API então retorna a resposta ao chamador. (Isso teria que ser chamadas síncronas quando a chamada para o serviço B exigir a resposta do serviço A. Serviços de pessoa e endereço separados do IE).
  • Faça com que o API Gateway chame cada serviço diretamente e consolide os dados na API antes de retornar a resposta.

Estou me inclinando para a segunda opção, pois o fato de os serviços conversarem entre si introduziria o acoplamento. Nesse caso, eu poderia apenas arquitetar um aplicativo monolítico. No entanto, existem algumas desvantagens sérias que posso pensar de cabeça para baixo com esta opção:

  • Fazer a API executar várias chamadas para vários serviços aumenta a carga no servidor da API, especialmente quando algumas dessas chamadas estão bloqueando.

  • Esse método significa que a API precisa estar "ciente" do que o aplicativo está tentando fazer (o IE Logic precisaria ser programado na API para lidar com a chamada dos serviços por vez e, em seguida, para consolidar os dados), e não apenas agir como um "ponto final" estúpido para os microsserviços.

Gostaria de saber qual é a abordagem padrão para esse problema e se há outra terceira opção que estou faltando?

KidCode
fonte
Você pode fornecer algum contexto? Qual é o seu aplicativo e o que ele está tentando fazer
Ewan
Meu palpite estaria entre as duas opções: Cada microsserviço se comunica com outros microsserviços, conforme necessário para realizar seu trabalho. E o gateway da API também pode ser considerado um microsserviço, que delega principalmente o trabalho para outros serviços.
Bart van Ingen Schenau
Eu diria que a composição de microsserviços no lado do servidor derrota o objetivo principal de ter microsserviços para começar. A idéia é tornar os serviços independentes e deixar a orquestração para o cliente. Mas talvez eu esteja sendo impraticável
Sridhar Sarnobat

Respostas:

21

Eu geralmente desaconselho que os microsserviços façam comunicação síncrona entre si, o grande problema é o acoplamento, isso significa que os serviços agora estão acoplados entre si, se um deles falhar, o segundo agora está total ou parcialmente disfuncional.

Eu faria uma distinção clara entre operações de alteração de estado e operações de leitura (CQS Command Query Separation ). Para operações de mudança de estado, eu usaria algum tipo de infraestrutura de mensagens e iria para o fogo e esquecer. Para consultas, você usaria a comunicação de resposta de solicitação síncrona e poderia usar uma API http ou apenas ir diretamente ao seu armazenamento de dados.

Se você estiver usando mensagens, também poderá consultar a assinatura de publicação para aumentar eventos entre serviços.

Outro ponto a considerar é o compartilhamento de dados (transacional) (em oposição às visualizações somente leitura) se você expor seu estado interno, o leitor poderá obter o estado errado dos seus dados ou a versão errada, e também potencialmente bloqueará seus dados?

Por último, mas não menos importante, tente fazer tudo o que puder para manter seus serviços autônomos (pelo menos no nível lógico).

Espero que isso faça sentido.

Sean Farmar
fonte
11

Depende do motivo pelo qual você precisa desses dados. Se for para interface do usuário, está perfeitamente bem. Além disso, é assim que deve ser. Chris Richardson tem uma boa explicação desse conceito e Sam Newman tem um ótimo artigo sobre um conceito muito semelhante chamado Backends for Frontends .

Mas se você precisar de alguma lógica, as chances são de que os limites de serviço estejam incorretos.

Existem várias características que o senso comum nos diz que nossos serviços devem possuir . Eles são:

  1. Baixo acoplamento. Se você fizer algumas alterações no serviço A, não deseja que elas afetem o serviço B.
  2. Coesão alta. Se você precisar implementar algum recurso, deseja que o menor número possível de serviços seja afetado.
  3. Alta autonomia. Se algum serviço falhar, você não deseja que todo o sistema esteja inoperante.
  4. Granularidade correta. Você não quer que seus serviços falem demais, pois sua rede é uma coisa mais complexa do que você imagina.
  5. Os serviços devem se comunicar por meio de eventos. Você não quer que seu serviço esteja ciente um do outro, pois reduz a capacidade de manutenção. Pense no que acontece se você precisar adicionar um novo serviço.
  6. Dados descentralizados. Um serviço não deve compartilhar a maneira como as informações são armazenadas. Assim como um bom objeto, ele expõe comportamento, não dados.
  7. Coreografia de serviço sobre orquestração.

Para conseguir isso, trate seus limites de serviço como recursos de negócios . Um processo formal de identificação de limites de serviço é semelhante ao seguinte:

  1. Identifique limites de nível superior. Gosto de pensar nelas como etapas pelas quais sua organização deve seguir para atingir sua meta de negócios e obter seu valor comercial. Você pode ter a idéia de etapas básicas examinando a cadeia de valor de Porter .
  2. Dentro de cada serviço, mergulhe mais fundo. Identifique as unidades independentes de crianças com suas próprias responsabilidades.
  3. Mente a maneira como eles se comunicam. Os serviços corretos se comunicam principalmente por meio de eventos. Pense na sua estrutura organizacional. A comunicação dentro deles é bastante intensa, embora normalmente alguns eventos externos sejam expostos.

Um exemplo de aplicação dessa abordagem pode ser de algum interesse.

Zapadlo
fonte
1

Eu me inclinaria para a segunda abordagem também por padrão, embora talvez não no seu "gateway API", mas consideraria completamente razoável criar um novo microsserviço cujo único objetivo era orquestrar solicitações para outros microsserviços e representar os dados em um formulário de nível superior. Em uma arquitetura de microsserviços, eu preferiria que os microsserviços "básicos" se comunicassem diretamente entre si.

Para tornar isso um pouco menos subjetivo, digamos que um serviço depende do outro se o primeiro exigir dados ou serviços do segundo, direta ou indiretamente . Em termos matemáticos, queremos que essa relação seja uma ordem parcial e não uma pré - encomenda . No formato de diagrama, se você plotou seu diagrama de dependência, deverá obter um diagrama de Hassee não possui nenhum ciclo (direcionado). (Em um diagrama de Hasse, as arestas são implicitamente direcionadas de baixo para cima.) Como orientação adicional, você deseja que os caminhos de cima para baixo sejam geralmente mais curtos. Isso significa que você deseja depender mais diretamente das coisas por padrão. Os motivos são que isso minimiza o número de coisas que podem dar errado para qualquer solicitação em particular, minimiza as despesas gerais e reduz a complexidade. Portanto, no caso "ideal" dessa métrica, o diagrama de Hasse teria apenas dois níveis. Obviamente, existem várias razões pelas quais você pode querer introduzir serviços intermediários, como armazenamento em cache, consolidação, balanceamento de carga, gerenciamento de falhas.

Para elaborar sua segunda preocupação de que o API Gateway seja "inteligente", um padrão que está ganhando força agora com estruturas como Falcor e Relay / GraphQL é fazer solicitações com mais especificações do que fazer para que o "API Gateway" possa genericamente execute essas especificações sem precisar saber o que isso GetTimelineimplica. Em vez disso, receberia uma solicitação como "solicite essas informações do usuário ao serviço do usuário e obtenha essas postagens do serviço de postagem" ou qualquer outra coisa.

Derek Elkins
fonte
0

Suspeito que a sua necessidade de serviços "entrar em contato" indica que você está prosseguindo com um sistema que não foi bem arquitetado, pois essa necessidade de microsserviços "entrar em contato" é uma forma de acoplamento que raramente aparece quando microsserviços são projetados adequadamente.

Você é capaz de explicar mais sobre o problema que está tentando resolver? Em inglês simples?

Ben
fonte