Arquitetura em aplicativo web multicliente

Olá pessoal, gostaria da opinião de profissionais mais experientes, que já tenham participado de algum projeto ligado ao cenário abaixo.

Será desenvolvido um sistema web, em java, onde os clientes se logam e utilizam funcionalidades diversas, cadastros, relatórios, gráficos, etc. Cada cliente deve acessar somente seus dados, cada cliente um banco (talvez), e o banco pode estar junto ao servidor do site ou no servidor do cliente (caso o cliente queira ter controle dos dados).

  1. Qual melhor forma de desenvolver esse cenário?
  2. A arquitetura como fica?

Obs.: Seria interessante citar exemplos. :smiley:

Agradeço a ajuda de todos.

Bem,
você não disse qual seria
o porte dos clientes, mas
sugiro que você use
uma arquitetura que permita
que o banco seja configurado
programaticamente, quando
o usuario acessar, pois a url do banco
será de acordo com o cliente.
Aqui no guj tem esse assunto
(como definir dinamicamente o banco
de dados).
Dessa maneira, voce vai ter uma base
de dados para cada cliente.
Sugestão: jsf, hibernate, mysql, spring.

Espero ter ajudado.

Primeiramente obrigado pelas dicas.

Os clientes são de pequeno porte, mas podem ser muitos (100-200). Quanto ao banco estou pensando em ser configurável mesmo.

Mas quanto ao site acessar o banco no servidor do cliente, o que acha?

vlw

Bom,
a arquitetura proposta dá suporte
a este acesso. A aplicação ficaria
em um servidor e a base de dados
em cada cliente.
Problema seria performance,
sugiro que no inicio as bases sejam por
cliente, mas no mesmo servidor da aplicação,
ou então na mesma rede.

[quote=horacio_barros]Bom,
a arquitetura proposta dá suporte
a este acesso…
[/quote]

Na verdade a performance é minha maior preocupação.

Obrigado.

Ola

Restrição de cada usuario acessar apenas os seus dados é uma restrição de dominio e isso deveria ser parte do seu Modelo (MVC, lembra?).

Nenhuma arquitetura vai impor isso a menos que vc tenha uma JVM para cada usuario, como se funcionasse a lá CGI-BIN.

A sua preocupação com performance é interessante porém se vc medir desde o começo vai ter alguma ideia dos gargalos. Boa parte deles podem se resolver com cache (seja de dados, seja cache do front-end) se o sistema for web e não exigir (quase) nada em tempo real. Por exemplo um forum é diferente de um home banking.

Se vc pensar em ter algo como 2 servidores web com um balanceador de carga na frente, compartilhando sessão via memcached, usando Hibernate e usando alguma solução para obter second level cache nas suas consultas ao banco de dados, vc tem uma receita que atende bem a boa parte dos sistemas web que precisam de escalabilidade e disponibilidade. Entretanto depende do que vc quer fazer.

Por exemplo, ja tive um sistema que era apenas uma “pagina”. usei sessão salva no cookie (criptografado) e cacheando toda a pagina. O que era diferente para cada usuario eu acessava via javascript e alterava o dom da pagina. Foi razoavelmente interessante. Tudo depende.

Então, usarei MVC sim, na verdade minha dúvida era se separava o banco ou deixava os dados de todos os clientes no mesmo banco (na realidade já pensava em bancos separados).

Desculpa a falta de conhecimento, mas não entendi muito bem. Então para cada cliente acessar o site, que direciona para o banco correto de acordo com o login, teria que rodar uma JVM separada? :S

Poderia indicar alguma documentação em java que possa ajudar?

Obrigado pela contribuição. :wink:

Olá Nevogei,

vc está procurando por MULTITENANCY.

Quanto vc usa uma ferramenta de plataforma como serviço (PaaS) como o GAE, setar um novo banco para um cliente é tão simples quanto:

Se quiser daber mais: https://developers.google.com/appengine/docs/java/multitenancy/multitenancy

Então, seja feliz, fuja de abordagens hosteadas onde vc precisa configurar um banco para cada cliente ou de ferramentas que não suportem esse atributo.

Tenho interesse em parcerias com projetos desse tipo.

Se quiser entrar em contato, fique à vontade.

O Hibernate 4 oferece suporte nativo a multitenancy, através da separação de schemas de bancos de dados. Dê uma olhada em http://www.infoq.com/br/news/2012/01/hibernate-4

[]'s

[quote=asaudate]O Hibernate 4 oferece suporte nativo a multitenancy, através da separação de schemas de bancos de dados. Dê uma olhada em http://www.infoq.com/br/news/2012/01/hibernate-4

[]'s[/quote]

Hibernate é passado, meus dados não precisam de colunas, meu banco tem o mesmo tempo de resposta para qualquer quantidade de registros… :wink:

Então, já tinha visto falar sobre mas não conheço. Vou dar uma olhada na documentação!

Estou tentando mostrar, na empresa, uma nova visão de trabalho, pois já estou cansado de trabalhar com tanta gambiarra e problemas, provenientes de desenvolvedores ruins :frowning:

Gostaria de ter a oportunidade de iniciar o projeto do zero, e o dono da empresa tem esse desejo, mas fazendo uma aplicação boa, manutenível.
Quem sabe não rola uma consultoria, para definir arquitetura e guiar um bom desenvolvimento.

Você conhece algo desenvolvido com multitenancy para servir como exemplo?

Obrigado pelas dicas. :slight_smile:

[quote=asaudate]O Hibernate 4 oferece suporte nativo a multitenancy…
[/quote]
Legal, bom saber. Obrigado pela dica.

Caramba, muito bom, o que você usa? NoSQL?
Você acha que essa forma de tratar os dados se encaixa em todo cenário?

Mais uma vez, obrigado pelas dicas.

Boa tarde, pessoal!
Vocês já viram o tanto de vídeo que tem aqui:
http://aprendacomigo.com.br/videos/category/java/82

Bom dia pessoal.

Estou iniciando no java e estou com a mesma situação do negovei
Vou desenvolver uma aplicação com as mesmas necessidades do sistema que o negovei postou.

Tenho uma dúvida que acredito que não tenha sido respondida ainda:
:arrow: No momento que o usuário acessar a URL do sistema e informar o usuário e senha, nesse exato momento, como o sistema saberia a qual cliente esse usuário pertence para ser direcionado para a base de dados do respectivo cliente?
O sistema teria que ter uma base de dados intermediária que fizesse a relação usuário X cliente? Teria algum número identificador no código do usuário que identificasse o código do cliente?

andre_salvati
Não entendi o que você quis dizer em "fuja de abordagens hosteadas onde vc precisa configurar um banco para cada cliente"
Você é de SP?

acho que vc confunde a logica orientada a objetos com a logica do banco de dados.

imagine que o banco de dados é um diretorio e nesse diretorio vc tem n fotos, dos seus clientes. como vc vai saber que foto é de que cliente?

vc pode criar sub diretorios para cada cliente, pode colocar o nome do cliente como prefixo das fotos, vc pode ter uma tabela que mapeie cliente -> foto. são varias abordagens diferentes mas elas devem ser transparente para o usuario pq o que ele quer é a foto dele.

modele os seus objetos.

vc tem um usuario e este usuario tem COISAS. logo vc pode ter uma tabela usuario e uma tabela de coisas onde uma coluna dessa tabela é um id de usuario. na hora que o cara logar vc pesquisa as COISAS daquele usuario. é a forma mais comum.

mas se vc usa um banco nosql vc pode ter um documento para cada usuario, etc. são varias possibilidades.

o problema de vc criar diferentes databases para isso é que não existe motivo para vc adicionar esta complexidade ao seu sistema. criar uma nova database é dificil, geralmente vc tem rotinas de backup e replicação de dados que dependem dos nomes de databases (logo vc pode perder dados fazendo isso de qq jeito). só faria isso se precisasse de alguma coisa muito hardcore e as soluções NOSQL podem ser melhores.

rcerullo,
vc pode fazer de varias formas:

Sugestão 1: Crie um banco de dados intermediario no qual vc teria
uma tabela com todos os usuarios, outra com as empresas que
comprarem o sistema, inclusive controlando um contas a receber.
Este banco seria acessado inicialmente pela aplicação.
Cada usuario cadastrado apontaria para uma determinada empresa
dona da copia do sistema.
Quando o usuario fosse autenticado, vc saberia qual base de dados
ativar.
Ou seja, teria uma base de dados para cada empresa.
Sugestão 2: Vc faria o usuario digitar uma chave de ativaçao,
com base nesta chave vc montaria o nome da base de dados,
tipo: se o usuario digitar 123456 vc inseria db antes, mais alguma coisa depois e
criaria a url do banco, fazendo a conexão.
Tem varias maneiras de resolver isso e fica simples e muito seguro.

Estou à disposição para ajudar se precisar.

Obrigado pelo retorno peczenyj

Acredito que não seja nem questão de eu estar confundindo… eu tinha planejado uma tabela num database de uso comum onde pudesse fazer a relação usuário X cliente.
Não fiquei muito confortável com essa solução pelo seguinte fato: se esse banco de dados ficar indisponível por algum motivo qualquer nenhum dos meus clientes irão se logar no sistema.
Imaginei que pudesse ter uma solução onde essa tabela no database de uso comum não fosse necessária.

Uma amiga minha deu a seguinte sugestão: colocar o id do cliente antes do id do usuário. Ex.:
id cliente = 01
id do usuário = 01.001
Assim, ao logar no sistema, o conteúdo antes do ponto seria o id do cliente, não precisando acessar nenhuma base de dados para saber a relação usuário X cliente.

Quanto a sua sugestão do banco nosql não tenho muito conhecimento a respeito. Como minha experiência em java é quase nada, acredito que lidar com banco nosql agora seja muita coisa para mim… prefiro focar no aprendizado do java primeiro e mais a diante ver a possibilidade de utilizar o banco nosql.

As condições principais que eu pensei em utilizar um database para cada cliente são:
:arrow: o tempo de transação de um cliente não concorrer com as transações dos demais clientes;
:arrow: se um database de um cliente estiver indisponível, não afeta a operacionalidade dos demais clientes;
:arrow: um cliente pode solicitar para o database dele ficar no servidor de sua responsabilidade e não no servidor da aplicação;
:arrow: entre outras.

Aproveitando a discussão…
Tenho um sistema que será migrado e será todo SAAS, uma app e um banco para todos clientes.
Porém, há clientes (a princípio seria só um), que, por causa das normas da empresa multinacional, precisa que o BD fique no servidor interno deles.
Qual seria a melhor abordagem?

PS: Acho que cai bem dentro do assunto do tópico.
PS: Abri anteriormente uma discussão sobre isso.
http://guj.com.br/java/270990-saas-e-bd-por-cliente

Obrigado pelo retorno horacio_barros

Coloquei um post um pouco antes do seu… acredito que já está contemplando o que você citou.

j0nny
Se este banco de dados ficar indisponível nenhum de seus clientes acessará o sistema… não é muito arriscado?

[quote=rcerullo]Obrigado pelo retorno horacio_barros

Coloquei um post um pouco antes do seu… acredito que já está contemplando o que você citou.

j0nny
Se este banco de dados ficar indisponível nenhum de seus clientes acessará o sistema… não é muito arriscado?[/quote]

Não, salesforce, SAP, e outras trabalham assim.
A questão é vc precisar trabalhar em uma base só para manter ela funcional para que não tenha problemas.
PS: Nosso sistema hj é uma base para cada cliente, é uma dor de cabeça desgraçada. Por isso quero uma base separada apenas para clientes muito “chatos”.