Micro-serviços e replicação de dados

14

Estou construindo um novo aplicativo e estava lendo sobre arquitetura de microsserviços. A arquitetura em si faz muito sentido do ponto de vista do desenvolvimento, implantação e gerenciamento do ciclo de vida. No entanto, um problema que surgiu foi sobre como lidar com dados mestre.

Por exemplo, eu tenho 2 aplicativos - por exemplo, aplicativo de vendas e aplicativo de emissão de bilhetes. Suponha que esses dois aplicativos sejam criados como microsserviços próprios. No entanto, esses dois aplicativos, quando implantados (supondo que sejam implantados separadamente, dizem que Sales usa MongoDB e Ticketing usam MariaDB), precisariam ter acesso às mesmas instâncias de dados mestre, como Contas, Produtos. Isso significaria que haveria um aplicativo proprietário para uma determinada entidade de dados mestre (por exemplo, para Contas, poderia ser o aplicativo Vendas) e uma parte interessada (por exemplo, o aplicativo Ticketing precisaria ter informações sobre Contas).

Existem várias maneiras de conseguir isso: - Replicação de dados do mestre para a parte interessada - Leitura síncrona do interessado para o mestre (a dependência da sincronização não é recomendada pelo paradigma da arquitetura de microsserviços) - Repositório centralizado próprio

Também dentro das Contas, pode haver uma parte principal que é comum para Vendas e Venda de ingressos (por exemplo, nome da conta, endereço etc.). No entanto, alguns aspectos da conta SOMENTE podem ser relevantes para vendas e outros SOMENTE relevantes para bilhética.

Quaisquer pensamentos / melhores práticas / opiniões sobre qualquer uma das opções acima mencionadas?

mithrandir
fonte
Você também não poderia criar contas e produtos como microsserviços? Separá-los completamente de uma "entidade de dados mestre". As vendas saberiam apenas sobre a venda de algum tipo de entidade, mas não precisam saber se a entidade é um Produto, Serviço ou qualquer outro tipo de entidade que você queira adicionar posteriormente.
precisa saber é o seguinte
Sim, isso seria possível. No entanto, aqui novamente o desafio é que o serviço central de 'Conta' precise ser modelado de maneira superconectada (ou seja, deve considerar atributos para Vendas, Ingressos, etc.). Isso meio que iria contra o paradigma do SRP.
Mithrandir

Respostas:

12

Eu fazia parte de uma equipe que construiu com sucesso uma arquitetura de microsserviços usando um barramento de serviço.

Inicialmente, acreditávamos que os microsserviços e uma arquitetura orientada a eventos nos permitiriam corrigir o banco de dados subjacente de dados compartilhados.

O que aprendemos foi que os microsserviços e uma arquitetura orientada a eventos exigiam que nos livássemos do banco de dados subjacente de dados compartilhados.

Acredito que os dados compartilhados são incrivelmente difíceis de se dar bem com os microsserviços - para mim é proibitivamente difícil. Eu recomendo não permitir que os serviços vejam os dados uns dos outros. Se você não puder consultá-lo, não poderá introduzir acidentalmente uma dependência.

Se você fazer partilhar dados, certamente apenas um serviço pode já possuir um registro; é o único serviço que grava no registro e qualquer outro usuário com os mesmos dados deve ter acesso somente leitura.

Infelizmente, mesmo essa pequena quantidade gerenciada de compartilhamento introduz um acoplamento significativo entre seus serviços. E se um serviço não quiser os dados dessa forma? Talvez ele queira uma agregação. Você solicita ao seu serviço "proprietário / gravação" para gravar dados agregados em benefício de outro serviço? Eu aconselho não.

E se o proprietário quiser persistir os dados em uma forma diferente? Então, todo serviço de leitor precisa ser atualizado. Isso é um pesadelo de manutenção.

A melhor solução que tivemos foi uma duplicação e desnormalização significativa de nossos dados. Os microsserviços mantinham suas próprias cópias dos dados com os quais se importavam.

As mensagens eram frequentemente publicadas com dados acompanhantes suficientes para processá-las.

Por exemplo, você pode imaginar que um serviço de remessa postal precise acompanhar as alterações em um endereço de cliente, caso precise publicar algo. Mas se a mensagem "item pronto para envio" incluir o endereço de destino como parte dos dados da mensagem, o serviço de envio não precisará mais rastrear os endereços alterados relacionados aos clientes; apenas endereços pontuais relacionados aos itens conforme eles são despachados.

Não posso sugerir como arquitetar soluções com dados sincronizados. Nossas soluções de dados foram construídas em torno da idéia de "eventual consistência".

Portanto, quando um cliente atualiza seu endereço, o serviço Endereço processa o comando inicial da interface do usuário. Quando seus dados estiverem corretos, ele publica um evento para notificar todos os outros serviços interessados ​​"Endereço do cliente atualizado" - com o endereço completo anexado como dados. Esses serviços atualizarão seus próprios armazenamentos de dados com as partes dos dados importantes para eles.

A idéia é que sempre que um serviço precisar executar uma ação importante, ele deverá ter uma cópia da informação atualizada o suficiente para agir corretamente, seja rastreado de forma independente ou como parte da mensagem à qual está respondendo.

perfeccionista
fonte
Você usa solução própria ou algo mais?
FrEaKmAn
2
Estávamos usando o NServiceBus - que apresenta idéias / estruturas para lidar com os fluxos de trabalho que ocorrem em cada serviço. A persistência pode acontecer através do RavenDB. Você pode achar que não deseja escolher uma tecnologia muito cedo - suas circunstâncias podem ser diferentes e tivemos problemas iniciais. Martin Fowler tem ótimos conselhos para as pessoas que começam nos microsserviços: martinfowler.com/articles/microservices.html - "... você não deve começar com uma arquitetura de microsserviços. Em vez disso, comece com um monólito, mantenha-o modular e divida em microsserviços quando o monólito se tornar um problema ".
perfeccionista
Em Short " A melhor solução que tínhamos era uma duplicação significativa e desnormalização dos nossos serviços de dados Micro mantido suas próprias cópias de dados que se preocupava.. "
DeFreitas
2

O armazenamento compartilhado de dados contraria a arquitetura do microsserviço. A questão é que, se houver contas, deve haver um serviço para lidar com elas e não deve haver outra maneira de interagir com essas contas além do serviço completo. Seus microsserviços não seriam independentes se eles compartilhassem armazenamento comum e qualquer alteração no mecanismo de armazenamento, validação ou outras restrições precisasse ser implementada nos dois serviços. Na prática, isso nunca acontece e logo leva a que os dois aplicativos sejam impedidos de alterações sérias.

Portanto, use um serviço como a única maneira de acessar seus dados, por exemplo, Contas. Pode acontecer que a implementação de um recurso em outro serviço exija uma alteração no serviço de Contas, e tudo bem. Lembre-se de que a lógica específica de qualquer serviço deve estar nesse serviço e o mínimo possível de material específico deve ser direcionado ao microsserviço de Contas.

Michał Kosmulski
fonte
0

precisaria ter acesso às mesmas instâncias de dados mestre, por exemplo, contas, produtos

Não é o mesmo. Cada microsserviço deve fazer seu próprio mapeamento para contas, produtos etc. Estamos assumindo que cada microsserviço terá uma maneira diferente de trabalhar com as entidades.

No Design Orientado a Domínio, isso é comum, onde cada contexto limitado (no mesmo aplicativo!) Pode mapear a mesma entidade de uma maneira diferente.

Se você precisar de mais informações, recomendo o livro Construindo microsserviços: Projetando sistemas refinados

Dherik
fonte
0

Você já considerou o conceito de registros de esqueleto com base em um conjunto mestre?

Por exemplo, um microsserviço lida com contas e o outro lida com produtos. Um terço pode manter registros de ambos para seu propósito específico de domínio.

Robert Christian
fonte