Estou achando difícil evitar a duplicação de dados ou um banco de dados compartilhado, mesmo para o design mais simples de microsserviços, o que me faz pensar que estou perdendo alguma coisa. Aqui está um exemplo básico do problema que estou enfrentando. Supondo que alguém esteja usando um aplicativo da Web para gerenciar um inventário, eles precisariam de dois serviços; uma para o inventário que gerencia os itens e a quantidade em estoque e um serviço de usuários que gerenciaria os dados dos usuários. Se desejarmos uma auditoria de quem estocou o banco de dados, podemos adicionar o ID do usuário ao banco de dados do serviço de inventário como o último estoque por valor.
Usando o aplicativo, podemos ver todos os itens que estão acabando e uma lista de quem os estocou da última vez, para que possamos pedir que eles os reponham novamente. Usando a arquitetura descrita acima, uma solicitação seria feita ao serviço de inventário para recuperar os detalhes do item de todos os itens em que a quantidade é menor que 5. Isso retornaria uma lista incluindo os IDs do usuário. Em seguida, uma solicitação separada seria feita ao serviço do usuário para obter o nome do usuário e os detalhes de contato da lista de IDs do usuário obtidos no serviço de inventário.
Isso parece muito ineficiente e não são necessários muitos serviços antes de fazermos várias solicitações para diferentes APIs de serviços, que, por sua vez, fazem várias consultas ao banco de dados. Uma alternativa é replicar os detalhes dos usuários nos dados do inventário. Quando um usuário altera seus detalhes de contato, precisamos replicar a alteração através de todos os outros serviços. Mas isso não parece se encaixar na idéia de contexto limitado dos microsserviços. Também poderíamos usar um único banco de dados e compartilhá-lo entre diferentes serviços e ter todos os problemas de um banco de dados de integração .
Qual é a melhor / correta maneira de implementar isso?
fonte
Respostas:
Eu perdi completamente onde você está sendo obrigado a duplicar.
Um princípio central dos microsserviços é que o serviço seja a única autoridade. Isso significa que o gerenciamento de inventário e usuário pode ser completamente separado. Eu projetaria o gerenciamento de usuários para que ele nem soubesse que o sistema de inventário existe.
Mas eu projetaria o sistema de inventário para que ele nunca armazene nada sobre usuários além de um ID do usuário. Isso cuida do seu problema de propagar alterações nas informações do usuário.
Quanto às coisas que precisam de informações de inventário e de usuário, como registros, auditorias e impressões, elas não são atualizadas à medida que as informações são alteradas. Eles são um registro do que era. Novamente, você não propaga mudanças.
Portanto, em todos os casos, quando você quiser as informações mais recentes do usuário, solicite o serviço de informações do usuário.
fonte
It seems counter-intuitive to move from a single relational database where I could get the inventory data and the user data with a join
Lembre-se de que "idealmente" há uma loja por serviço (ou mais!). Portanto, não há nada como "junção" entre "limites". O motivo é simples: o DB gera acoplamento entre os serviços. Ao contrário da sugestão do @CandiedOrange, acho que podemos duplicar um mínimo de dados de um serviço para outro. Estou me referindo a dados que provavelmente não serão alterados. Se este dups melhora a eficiência e performance (e ambos são obrigatórios) os "prós" provavelmente off-set os "contras"De acordo com o e- book da Microsoft sobre arquitetura de microsserviço , não há nada errado com a duplicação de dados. Basicamente, a duplicação de dados aumenta a dissociação entre os serviços e, portanto, fortalece suas funções como uma única autoridade. Uma passagem relevante:
fonte
De fato sim.
É verdade que, em um monólito, você pode ter um modelo de inventário que consulta os itens relevantes, alimentá-lo em um modelo de usuário e obter os mesmos dados.
Ou você pode ir além, se você os tiver no mesmo banco de dados relacional e escrever SQL que o banco de dados tomará a tabela de inventário e a tabela de usuários, isso faz alguma mágica e você obtém os dados que procura.
Independentemente de como você o faça, em algum lugar haverá um código que buscará essencialmente uma lista de IDs de usuário do sistema de inventário, as alimentará no sistema do usuário e compilará uma lista de dados.
A pergunta que você precisa responder é sobre desempenho e manutenção e outras qualidades "suaves".
O principal benefício dos microsserviços é o dimensionamento. Se você tiver dez mil usuários em uma máquina e for um pouco lento, poderá adicionar outra máquina e o sistema se tornará duas vezes mais rápido. Adicione mais oito e é dez vezes mais rápido. (Escala linear é provavelmente otimista, mas é o ideal e não que razoável esperança para.)
E isso é por serviço . Se o sistema de inventário é o gargalo, ele é usado para mais do que relatórios sobre usuários, você pode adicionar mais máquinas apenas a esse serviço . As máquinas também podem ser especializadas; esse serviço precisa de muita memória, esse serviço faz cálculos pesados e precisa de mais CPU.
Se você não precisar do dimensionamento, há outro benefício dos microsserviços: eles são modulares . É claro que aplicativos monolíticos também podem ser modulares, e você tem um banco de dados normalizado e ... mas, na prática, as paredes entre os módulos são como paredes de vidro no melhor caso, e as linhas na areia no pior. Os microsserviços são separados por aço sólido.
Se o sistema do usuário pegar fogo literalmente, isso não afetará nem um pouco o sistema de inventário. Você não poderá imprimir relatórios bonitos sobre quem estocou o quê, mas os clientes poderão fazer pedidos com segurança, sabendo que os itens estocados estão lá.
E você não duplica dados em microsserviços , assim como em um banco de dados relacional (*). Em um banco de dados relacional, você pode fazer uma junção e o equivalente é mesclar as listas no código como descrito.
Você também pode adicionar uma visualização , o equivalente é adicionar um novo serviço que faz a mesclagem para você; isso resultaria em três solicitações; um para o novo serviço e, em seguida, esse serviço executa os dois originais. Os bancos de dados relacionais têm coisas sofisticadas que otimizam as visualizações, que precisam ser implementadas no nível de serviço. Você não o obtém "de graça".
O armazenamento em cache é diferente da duplicação de dados, pois se dois valores não correspondem, você sabe qual deles está errado. É frequentemente usado em microsserviços para aumentar a disponibilidade à custa da consistência (teorema da CAP). Como os bancos de dados relacionais abatem completamente a disponibilidade no altar de consistência, é menos comum neles. Eu diria que não há nada inerente nos microsserviços que facilite o armazenamento em cache, mas, na prática, o cache é uma preocupação principal e que facilita o armazenamento em cache nos microsserviços .
(*) Se fizer sentido duplicar dados em um enxame de microsserviços, provavelmente faria sentido no banco de dados relacional equivalente a.
fonte