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?
fonte
Respostas:
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.
fonte
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:
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:
Um exemplo de aplicação dessa abordagem pode ser de algum interesse.
fonte
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
GetTimeline
implica. 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.fonte
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?
fonte