Pessoal, gostaria de discutir um pouco a respeito de uma melhor forma de aplicar uma integração entre 2 sistemas que compartilham informações, mas que estão armazenadas em bancos de dados diferentes, por questões técnicas. Já trabalhei de diversas maneiras e já vi também de tudo um pouco neste tipo de integração e gostaria de discutir a respeito.
Não queria ouvir respostas do tipo… contrate um consultor!
Vamos imaginar o seguinte cenário:
Temos um cadastro de clientes, e este cadastro pode ser atualizado tanto por uma solução desktop, dentro de uma empresa, quanto pelos próprios clientes (solução web).
A empresa esta localizada em uma área rural e o link é de 64Kbits… Existem cerca de 10 funcionários trabalhando sob. este cadastro. O baixo link impossibilita um unico sistema Web, para ambos os acessos. Não há na região possibilidade de aumentar este link. Desta maneira temos 2 servidores de banco de dados, um dentro da empresa e outro na internet hospedado em um grande provedor e 2 aplicações, uma desktop que manipula o banco de dados local e outra que manipula o banco remoto.
Precisamos integrar estes dados, não exatamente em tempo real (por causa da limitação do link), mas com o menor delay possível.
Vou detalhar agora algumas soluções que já vi por ai e até pensei em fazer, para discussão e gostaria que o pessoal desse sua opnião a respeito e sugerisse a “melhor solução” ou a melhor forma de resolver este problema.
Integração entre banco de dados.
Os bancos SQL Server (ou outro) estarem configurados, para replicar as alterações entre eles. Acredito que esta seria a melhor solução, visto que estamos trabalhando na camada de banco de dados, e com uma solução nativa sem necessitar desenvolvimento. Entretanto vejo alguns problemas:
Geralmente há excesso de tráfego gerado pelas ferramentas, problemas com locks e “destruição” da banda do pequeno link disponível. Talvez essa seja a melhor solução quando se tem um bom link.
Integração através de Web Services.
Sempre que alguma alteração for realizada em algum dos bancos, é acionado um Webservice para atualizar o banco remoto. O problema que vejo neste caso é que dependendo do congestionamento da banda naquele momento, a gravação poderá demorar e causar insatisfação do usuário.
Criação de um robô
Este robô, baseado em algum timestamp de alteração dos dados, coleta uma série de dados de uma lado e sincroniza com o outro. O robô pode rodar dentro do próprio banco de dadados (Job/Procedure), como em um aplicativo a parte. O problema que vejo é como tratar situações que tiveram alteração dos 2 lados no mesmo intervalo de tempo (já que não se tem locks) e também o fato de trafegar muitos dados durante a execução do robô. A maior parte deste tipo de solução deixa o robô rodar de madrugada e acaba gerando um atrase de até um dia na atualização das informações.
Utilizar servidores de fila e MDBs.
Uma solução que pensei ser possível mas não se seria uma boa, seria gravar as alterações (uma espécie de logs de transações), através de mensagens em um servidor de fila… desta forma implementaria MDBs para efetuar a sincronização dos registros através de Webservices. Poderia também ser escalavel dependendo do horário. Uma duvida seria como gerenciar a parte de modificações simultâneas, já que não existiriam locks! Talvez baseado em algum timestamp e histórico???
Gostaria de receber as opniões do pessoal e também sugestão de implementações.
Primeiro tem que analisar as restrições mais óbvias:
Esse cadastro realmente precisa ser local e web? Normalmente um dos lados é um “plus” no projeto, não sendo indispensável;
Caso precise dos dois lados, qual é o prioritário? O cadastro mais importante ou de maior volume viria de onde? Quem seria o master/slave?
Será que você não consegue uma internet 3G, via satélite ou outra abordagem para conectar a região rural na web?
Como você lidaria com inconsistências/colisões?Por exemplo, um cliente tem um endereço local, mas na web o endereço foi editado ou não existe mais. Esse tipo de situação pode ser atenuada via design, modelando o banco com pouco ou nenhum dado interrelacionado.
Acho que com isso dá pra analisar melhor o problema.
Vamos lá…
O caso não é real, mas já passei por situações parecidas e o objetivo principal seria discutir uma melhor solução.
Mas vamos pensar então no caso mais real próximo a este cenário (cenário problemático com link), onde a solução adotada foi fazer uma integração por robô durante a madrugada (e realmente tenho duvidas até que ponto foi a melhor solução, pois não fui eu quem adotou a mesma).
Se fosse possivel ser somente Web, mas o link inviabiliza o acesso de varios operadores no sistema Web, portanto precisa estar dos 2 lados.
Ambos terão cargas parecidas, porém o cadastro da empresa é prioritário. Ele seria o master e o cadastro web seria o slave.
Nesse caso, infelizmente não teve possibilidade de nenhuma outra conexão. E gostaria de saber também hoje sem possibilidade de conexão maior, qual a melhor opção.
Também gostaria de discutir sobre a melhor maneira de fazer isso. Sempre que utilizei coisas parecidas, a alteração foi baseada em timestamp. Na solução usada, também foi baseada em timestamp. Ele acabava processando também todos os relacionamentos.
Há inúmeras opções para fazer isso. Uma delas é colocar o banco master no lado web e manter todos os cadastros lá. O aplicativo local poderia enviar requisições de cadastro para web, que processaria a requisição e retornaria o resultado. A cada sucesso os dois lados registram um número de equivalência. O aplicativo local seria sincronizado uma vez por dia, de madrugada, e qualquer listagem seria offline. Caso não haja conectividade, o aplicativo local pode realizar cadastros também, mas a sincronização deveria resolver as inconsistências baseado no número de equivalência. O que não fosse resolvido você teria que checar manualmente. E a deleção seria lógica. Estou supondo que não há uma boa infra-estrutura para colocar um servidor na área rural…
Já tive 3 casos parecidos!
Dois deles usei a própria solução de integração do banco de dados (Um com SQL Server e outro com Mysql).
Ambos não tinham a necessidade de efetuar novos cadastros no slave.
Já no caso que tive necessidade de cadastro no slave, utilizei integração via MDB e ActiveMQ, e utilizei um hash para número de equivalência que foi sugerido no post. Com isso saberia quais dados eram gerados pelo slave e precisavam ser enviados ao master. Nos casos de registros pré-existentes, foi necessário implementar uma regra de mescla de dados, entretanto não é um caso tão comum para a aplicação.
É importante centralizar o servidor master, em algum lugar que tenha boa infra. Se você possui varios slaves, com certeza centralizar o banco master em algum provedor web é o melhor a ser feito!
Eu tenho um banco de dados local e uma na web, ambos sql server, hoje faço em algumas tabelas replicação, em outras tenho um sistema robo que faz isto, estou querendo criar um webservice, vc acha que seria uma boa solução?
Depende muito da necessidade do seu negócio e como vai acessar este webservice.
As vezes é melhor abrir uma conexão direta com o banco de dados remoto!