É uma prática ruim para os serviços compartilhar um banco de dados em SOA?


17

Recentemente, tenho lido os Padrões de Integração Empresarial de Hohpe e Woolf, alguns dos livros de Thomas Erl sobre SOA e assistido a vários vídeos e podcasts de Udi Dahan et al. nos sistemas CQRS e Event Driven.

Os sistemas no meu local de trabalho sofrem com alto acoplamento. Embora cada sistema teoricamente tenha seu próprio banco de dados, há muitas junções entre eles. Na prática, isso significa que há um enorme banco de dados usado por todos os sistemas. Por exemplo, há uma tabela de dados do cliente.

Muito do que li parece sugerir dados desnormalizados para que cada sistema use apenas seu banco de dados, e quaisquer atualizações em um sistema sejam propagadas para todos os outros usando mensagens.

Eu pensei que essa era uma das maneiras de impor os limites em SOA - cada serviço deveria ter seu próprio banco de dados, mas então li o seguinte:

/programming/4019902/soa-joining-data-across-multiple-services

e sugere que esta é a coisa errada a fazer.

Segregar os bancos de dados parece uma boa maneira de dissociar os sistemas, mas agora estou um pouco confuso. Este é um bom caminho a seguir? É sempre recomendável que você separe um banco de dados, digamos, um serviço SOA, um contexto delimitado por DDD, um aplicativo etc.?


A pergunta original que você vincula está errada. A pergunta em si está errada, como a maioria das respostas. SOA não é dividir um único aplicativo em serviços discretos e particionar seus dados.
Jeremy

Entendo que a pergunta está errada, foram as respostas que me fizeram reavaliar meu pensamento.
Paul T Davies

Eu acho que os serviços devem ser acoplados
B Sete

Respostas:


12

A dissociação funciona apenas se houver realmente separação. Considere se você possui um sistema de pedidos:

  • Tabela: CLIENTE
  • Tabela: ORDER

Se é tudo o que você tem, não há razão para dissociá-los. Por outro lado, se você tiver este:

  • Tabela: CLIENTE
  • Tabela: ORDER
  • Tabela: CUSTOMER_NEWSLETTER

Você pode argumentar que ORDER e CUSTOMER_NEWSLETTER fazem parte de dois módulos totalmente separados (pedidos e marketing). Talvez faça sentido movê-los para bancos de dados separados (um para cada tabela) e os dois módulos compartilhem o acesso à tabela CUSTOMER comum em seu próprio banco de dados.

Ao fazer isso, você simplifica cada módulo, mas aumenta a complexidade da sua camada de dados. À medida que seu aplicativo cresce, posso ver uma vantagem em separar. Haverá mais e mais "ilhas de dados" que realmente não têm relação uma com a outra. No entanto, sempre haverá alguns dados que cruzam todos os módulos.

A decisão de colocá-los em diferentes bancos de dados físicos normalmente se baseava em restrições do mundo real, como frequência de backups, restrições de segurança, replicação para diferentes localizações geográficas, etc. Isso pode ser tratado de maneira mais simples com diferentes esquemas ou visualizações.


5
-1. Eles só devem estar em bancos de dados separados se houver um motivo para colocá-los lá. Você precisa "tirar algo disso" porque certamente torna seu aplicativo mais complexo.
scottschulthess

1
Eu acho que vale a pena enfatizar a importância de separar as duas áreas de funcionalidade na camada de dados (seja usando esquemas separados ou outra coisa). Cada módulo deve acessar apenas os dados do outro módulo através da API do outro módulo - isso é semelhante aos princípios de encapsulamento OO. Ou seja, não compartilhe um esquema entre vários módulos. Além disso, eu recomendaria contra visualizações, preferindo expor dados via. uma API.
31514 Chris Chris

@scottschulthess sim, você precisa pesar o custo da complexidade e, se não valer a pena, você simplesmente não pode se dividir em serviços. Dividir, mas usando um banco de dados compartilhado que encontrei, é a pior das 3 opções.
precisa

8

Onde trabalho, temos um ESBàs quais 6 aplicativos diferentes (ou devo dizer "pontos de extremidade") estão conectados. Esses 6 aplicativos funcionam com 3 esquemas diferentes do Oracle em 2 instâncias de banco de dados. Alguns desses aplicativos coexistem no mesmo esquema, não porque estejam relacionados, mas porque nossa infraestrutura de banco de dados é gerenciada por um provedor externo e a obtenção de um novo esquema leva apenas uma eternidade (além disso, é claro que não temos acesso ao DBA) ... leva tanto tempo que, a certa altura, pensamos em reutilizar um esquema existente "temporariamente" para poder continuar o desenvolvimento. Para impor a "separação" dos dados, os nomes das tabelas são prefixados, por exemplo "CST_" para o cliente. Além disso, temos que trabalhar com um esquema que, por alguns motivos válidos, não podemos mudar absolutamente ... É estranho, eu sei. Claro, como sempre acontece, "temporariamente"

Nossos diferentes aplicativos se conectam ao respectivo esquema de banco de dados e trabalham com seus próprios pacotes PL / SQL e nos proibimos de interagir diretamente com tabelas / dados que estão fora do domínio do aplicativo.

Quando um aplicativo conectado ao ESB precisa de informações fora de seu domínio, ele chama o serviço relacionado no ESB para obter os dados, mesmo que essas informações estejam de fato no mesmo esquema, exigindo, em teoria, apenas uma pequena declaração de junção em uma das solicitações SQL .

Fazemos isso para poder dividir nosso domínio de aplicativo em diferentes esquemas / bancos de dados e, para que os serviços no ESB ainda funcionem corretamente quando isso acontece (é Natal em breve, estamos com a mão na massa)

Agora, isso pode parecer estranho e horrível do lado de fora, mas há razões para isso e eu só queria compartilhar essa experiência concreta para mostrar que um ou mais bancos de dados não são tão importantes. Espere, é isso! , por vários motivos (+1 para Scott Whitlock, consulte o último parágrafo sobre backup e que meus problemas podem levar a problemas). não sou um DBA. Por fim, todos os seus bancos de dados pertencem ao seu "datawarehouse corporativo", certo?

Finalmente, não vou reformular o último parágrafo de Scott Whitlock, particularmente este

Eu não separaria tabelas em diferentes bancos de dados físicos apenas por causa da separação de preocupações.

é realmente super importante. Não faça isso se não houver motivo.


8

Eu já vi os piores pesadelos possíveis na arquitetura de software devido à integração de dados e a melhor arma contra esse tipo de bagunça que eu encontrei até agora em contextos limitados no estilo DDD. O que não está muito longe de "SOA feito corretamente", em certo sentido.

No entanto, os dados em si não são a melhor maneira de atacar o problema. Deve-se focar no comportamento esperado / necessário e levar os dados para onde for importante. Podemos acabar tendo alguma duplicação dessa maneira, mas isso normalmente não é um problema em comparação com os blocos para a evolução do sistema quase sempre associados a arquiteturas integradas a dados.

Para simplificar: se você estiver procurando por sistemas pouco acoplados, não fique acoplado aos dados. Escolha sistemas encapsulados por weel e um canal de comunicação bem estruturado no meio, atuando como "língua franca".


1
E ... respondendo diretamente à pergunta do título: "Sim, consideraria uma prática arriscada compartilhar um banco de dados em uma SOA". Se parecer a coisa mais razoável a se fazer, provavelmente haverá uma falha grave no design.
ZioBrando

7

A dissociação de bancos de dados e a manutenção dos dados consistentes entre eles são uma tarefa no nível de especialista. É muito fácil cometer erros e acabar com os problemas de duplicatas, etc., que o sistema atual foi projetado para evitar. Francamente, pegar um sistema funcional e fazer isso é praticamente uma garantia de introdução de novos bugs sem valor real para os usuários.


1

Se feito corretamente, separar preocupações de negócios em diferentes bancos de dados (ou pelo menos esquemas diferentes) é uma virtude .

Por favor, veja a descrição de Martin Fowler do Padrão CQRS :

À medida que nossas necessidades se tornam mais sofisticadas, nos afastamos constantemente de [tratar um sistema de informações como um armazenamento de dados CRUD] ... A mudança introduzida pelo CQRS é dividir esse modelo conceitual em modelos separados para atualização e exibição ... Há espaço para variações consideráveis aqui. Os modelos em memória podem compartilhar o mesmo banco de dados; nesse caso, o banco de dados atua como a comunicação entre os dois modelos. No entanto, eles também podem usar bancos de dados separados , tornando efetivamente o banco de dados do lado da consulta por um ReportingDatabase em tempo real. Nesse caso, precisa haver algum mecanismo de comunicação entre os dois modelos ou seus bancos de dados.

E os princípios arquitetônicos do NServiceBus :

Separação de Consulta de Comando

Uma solução que evita esse problema separa comandos e consultas no nível do sistema, mesmo acima do cliente e do servidor. Nesta solução, existem dois "serviços" que abrangem o cliente e o servidor - um encarregado de comandos (criar, atualizar, excluir) e o outro encarregado de consultas (lido). Esses serviços se comunicam apenas via mensagens - um não pode acessar o banco de dados do outro ...

E Segregação de Responsabilidade por Comando e Consulta (CQRS)

Segregação de responsabilidade de comando e consulta

A maioria dos aplicativos lê dados com mais frequência do que os dados gravados. Com base nessa afirmação, seria uma boa ideia criar uma solução em que facilmente você possa adicionar mais bancos de dados para leitura, certo? E se configurarmos um banco de dados dedicado apenas para leitura? Melhor ainda; e se projetarmos o banco de dados de uma maneira para que seja mais rápido lê-lo? Se você projetar seus aplicativos com base nos padrões descritos na arquitetura CQRS, terá uma solução escalável e rápida na leitura de dados.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.