Arquitetura ideal para migração de sistema Desktop

E aí galera, gostaria de ouvir a opnião de vocês sobre qual seria a melhor alternativa para o meu caso…

O que tenho hoje:

Uma aplicação de médio porte, uns 10 usuários simultâneos no mínimo, porém com processamento de informações intenso, inclusive a comunicação com o banco de dados. Esta aplicação é crítica e utilizada 24 horas.

A arquitetura dela é bem simples: Alguns objetos RMI no servidor principal (no qual também está o banco de dados) e a interface gráfica e demais classes pertinentes ao cliente são atualizadas via Java WebStart.

Nesse pequeno universo eu sofro MUITO para atualizar as classes, pois tenho que derrubar o servidor RMI, atualizar meu arquivo Jar e depois subir novamente o servidor, causando aí a indisponibilidade do sistema durante uns 10 minutos, pois o servidor está em outro local e o FTP demora pra c…

Agora a bomba. Esta aplicação ganhará diversas novas funcionalidades, similares porém com outros propósitos, dobrando a quantidade de usuários e também sua importância na empresa.

Acho que é a hora de mudar essa arquitetura. Aproveitar este refactoring que faremos e alterar tudo.

O que vocês acham? Web está fora de cogitação…

Valeu!

Olá

Troca o servidor RMI por um servlet engine que geralmente tem melhor performance. Crie um servlet para receber as comunicações entre o cliente e o servidor usando URLConnection (com ajuda de HttpClient). Normalmente o servlet engine não precisa parar quando você instala um novo jar desde que você o empacote como war.

O FTP você deve fazer para um outro diretório diferente. Ao fim dele, você simplesmente executa um script que move o novo arquivo .war recem transferido para o diretório da aplicação (webapps se o servlet engine for o tomcat). Cada novo arquivo .war deve ter nome diferente do anterior mas o jar precisa ser com o mesmo nome.

Como são apenas 10 clientes, acho que pode continuar usando Java Web Start que tem o grave inconveniente de atualizar todos os clientes juntos se eles abrem na mesma hora.

Sugestão: mantenha sempre no servidor as versões antigas porque se der caca em uma atualização você tem condições de voltar a anterior rapidamente.

[]s
Luca

Pois é, a gente faz esse tipo de coisa tudo via Ant, é automatizado, o inconveniente é essa parada mesmo. O Jar tem algo em torno de 3 megas, e a atualização é demorada pacas pros usuários que não estão na filial onde está o servidor.

Seria legal usar um JBoss nesse caso? Nunca trabalhei com EE que não seja Web, é interessante ou pro tamanho da coisa é matar uma mosca com bala de canhão?

Pensamos também em Webservice no lugar dos RMI’s…

O fato é que estas “funcionalidades” na verdade são a migração de um sistema atual para Java, e como são coisas similares, vamos juntar os dois, que já era um projeto antigo.

Porém, gostaríamos de atualizar em separado estes dois sistemas (que agora serão um) para que não afete o negócio de nenhuma das partes, ou, fazer uma atualização que não pare nada!

Olá

Para porque é RMI, se fosse servlet não precisaria.

Neste caso o assunto é outro. Já não está mais falando do servidor RMI. Aqui a solução é criar uma sistema seletivo de dowload só das classes alteradas e fazer um ClassLoader customizado no cliente para reconhecê-las e carregá-las na memória. É factível, já participei de um projeto de um sistema assim.

Para que? Só para servir servlets? É claro que não. O JBoss usa o tomcat ou o Jetty para servir servlets.

Você poderia pensar em usar o Apache XML-RPC para enviar as mensagens para o servlet. Mas aí você teria que alterar todas as atuais mensagens do sistema. Melhor deixar web services de lado. Quando muito, se for mudar as mensagens e quiser enviar classes serializadas para o servlet engine, use o XStream.

[]s
Luca

Luca, eu noto que você sempre recomenda Servlets + HttpClient em vez de RMI, Session Beans e etc.

Será que com o EJB 3 não ficaria mais simples usar Session Beans do que usar Servlets + HttpClient e criar um protocolo? Qual a sua opinião?
Servlets + HttpClient não vai te obrigar a criar um protocolo, acrescentando uma complexidade a mais?

Olá

Acho que ainda vai demorar para que eu recomende alguma coisa no cliente que não seja baseado em HTTP passando pela porta 80.

Pelo que conheço de redes e de administradores de redes, não vejo outra alternativa. E já vi gente reclamando de HTTP mas nunca me inclui entre eles porque, bem ou mal, foi o HTTP que propiciou todo este mundo conectado que temos hoje.

Mesmo que você passe o RMI por um tunel HTTP eu não gosto de usar EJBs no cliente. A minha visão de cliente é que ele precisa ser o mais desacoplado possível do servidor e eu vejo o uso de EJBs no cliente como a criação de um vínculo.

Mas sei de gente que usa EJBs no cliente com muito sucesso. Só não sei se eles continuarão felizes se um dia sua arquitetura mudar para SOA e outros clientes precisarem acessar seus serviços.

Quanto a criação de protocolo, se você quiser algo padronizado e mais simples do que SOAP, use o Apache XML-PRC (com servlet). Ou então o próprio SOAP que também não é assim tão difícil.

[]s
Luca

O Java WebStart - na verdade o JNLP, especificado pela JSR-51 - jah possui um esquema de versionamento que permite a distribuicao automatica apenas da “diferenca” das versoes, com um protocolo conhecido como jardiff. Jah pus em producao e funciona muito bem, exceto em algumas versoes mais antigas do JDK 1.4.2, em que existe um bug na escrita do jar que forca o usuario a, ocasionalmente, ter que tentar acessar a aplicacao mais de uma vez ateh ser bem sucedido (num caso pessimista, no maximo n + 1 vezes, sendo n o numero total de jars da aplicacao; no caso em questao, o pior que vi foi n / 5).

[quote=RaulCarlin]Seria legal usar um JBoss nesse caso? Nunca trabalhei com EE que não seja Web, é interessante ou pro tamanho da coisa é matar uma mosca com bala de canhão?

Pensamos também em Webservice no lugar dos RMI’s…[/quote]

Pra resolver o problema da comunicacao remota, recomendo que voce continue utilizando um protocolo binario e compacto, ateh porque voce disse que hah problemas de download. RMI “cru” eh um tanto pesado no servidor a menos que voce faca um esforco grande de programacao para compensar isso.

O ideal eh ter uma tecnologia no servidor que permita implementar servicos e gerencia-los. Utilizar EJB eh uma opcao, mas nao a unica saida. Em casos como esse, desacople a tecnologia utilizada para interligar cliente e servidor, colocando-a numa camada invisivel da aplicacao, utilizando dynamic proxies em cima de interfaces ou AOP em cima de POJOs.

Uma implementacao desse conceito eh a remotabilidade transparente do genesis, que permite que a integracao seja feita conforme necessario.

Acho que vão. O uso de uma Arquitetura Orientada a Serviços (SOA) pressupõe a coexistência entre quaisquer protocolos/plataformas/linguagens no parque de software de uma organização.

Olá

Bem lembrado, eu tive problemas com jardiff usando Java 1.4.1.

Mas mesmo que o jardiff funcionasse 100%, ele não evitaria todos os downloads ao mesmo tempo que era meu principal problema no servidor já que todas as lojas abriam na mesma hora. Daí a necessidade de um esquema especial. Aliás, no livro do Mauro Marinilli sobre JNLP de 2002, ele já reclamava da falta da possibilidade de download seletivo no JNLP.

[quote=mister__m] Em casos como esse, desacople a tecnologia utilizada para interligar cliente e servidor, colocando-a numa camada invisivel da aplicacao, utilizando dynamic proxies em cima de interfaces ou AOP em cima de POJOs.

Uma implementacao desse conceito eh a remotabilidade transparente do genesis, que permite que a integracao seja feita conforme necessario.[/quote]

Não acho que a solução do genesis web signifique o desacoplamento ideal PORÉM acho que significa um enorme avanço sobre o uso de RMI. Realmente uma mão na roda para projetos deste tipo. E com a vantagem de deixar o trabalho de baixo nível de rede para o JBoss.

Acho que eu preciso um dia brincar com a trinca JMeter + GlassBox + Wireshark em cima de uma aplicação com o genesis para ganhar confiança mas ele me impressiona muito bem.

[]s
Luca

Olá

Não entendi bem onde você discordou de mim e por isto tentarei me explicar melhor.

Em princípio não gosto de EJBs no cliente por 2 motivos:

  1. Complica o desenvolvimento e necessita de codificador mais experiente
  2. Necessita de servidor que entenda um protocolo de EJBs que são estranhos para outras aplicações não baseadas em EJBs

Para resolver o problema 1. se pode adotar soluções como o genesis web que se encaixa com perfeição e deve dar um ganho enorme de produtividade ao desenvolvimento.

Fazendo um parêntesis, SOA significa arquitetura baseada em serviços, não exatamente baseada em web services e nem propriamente aberto na Internet.

Em termos de arquitetura, sempre objetivo o menor acoplamento possível. Sabendo que há possibilidades de se adotar soluções menos acopladas do que com EJBs, em igualdade de condições, eu priorizo uma solução sem EJBs que possa ser acessada por outros clientes (clientes não humanos).

[]s
Luca

Luca, eu nao entendi exatamente como isso era um problema pra voce. O servidor ficava em pico de processamento? A rede “entupia”? As lojas mais importantes nao conseguiam fazer download?

Apenas para deixar mais claro, o que considero ideal eh esconder completamente como a comunicacao com o servidor eh feita; isso deve ir pra “debaixo dos panos”. Desenvolvedores de codigo de negocio nao devem ser expostos aos detalhes de implementacao de EJB, RMI, SOAP, Webservices para desenvolver suas aplicacoes.

Olá

A aplicação travava nas agências e lojas porque o servidor não tinha largura de banda para o download de todos ao mesmo tempo. Porém o pior problema era que o usuário perdia a paciência com a longa espera e rebootava a máquina achando que resolveria. O servidor na verdade fazia muito mais downloads do que o necessário. Isto acontecia no Banco Postal na época em que o servidor tinha 8Gb de banda que era insuficiente para dar conta de bem mais de 10 mil agências. Na época a gente ainda não usava o jardiff que só fui usar em uma outra aplicação de captura de cartão de crédito também com muitos clientes Java Web Start.

Mas se o cliente tivesse aprovado o projeto, poderia ter sido criado um banquinho de dados no servidor para liberar os downloads de acordo com um escalonamento desde que o motivo da atualização não seja um erro gravíssimo.

Perfeito, só por isto o genesis já tem seu valor. E o bom dele é que faz mais coisas.

[]s
Luca

mister__m

Você já utilizou genesis? O que ele quer dizer com a restrição “Não pode ser estático nem manipular membros estáticos”? O fato de não permitir um método estático tranquilo, mas o que ele considera uma manipulação? Acesso ou alteração?

Se não puder acessar membros estáticos dentro do @Remotable então está fora de cogitação, mesmo tendo me interessado logo de cara pela sua facilidade… o meu projeto tá completamente OO, cheio de interfaces e uma porrada de variáveis estáticas que servem pra um zilhão de coisas, se não puder utilizá-las no servidor vai ser em vão, não vou entupir o meu cliente de processamento sendo que temos um servidor muito parrudo pra isso…

Por enquanto estou trabalhando na idéia do Luca, utilizando HTTP com um Servlet brincando de RMI e fazendo persistência com Hibernate (outra novidade que entrou no projeto)…

Valeu pela atenção!

Olá

Ele é o criador do genesis

Se tem muitas variáveis estáticas então dificilmente será considerado como completamente OO.

O genesis justamente resolve parte dos problemas de quem usa RMI. A menos que você abandone o uso de RMI, no seu caso valeria a pena dar uma olhada no genesis.

A minha sugestão seria totalmente sem RMI.

[]s
Luca

[quote=RaulCarlin]mister__m

Você já utilizou genesis?[/quote]

Criei :slight_smile:

Veja esse snippet da documentacao:

Basicamente, o problema eh que os valores estaticos nao serao sincronizados com o servidor, gerando uma serie de efeitos indesejados. No seu caso, nao haverah problema algum, pois sua arquitetura jah implica que nao hah sincronia entre os membros estaticos de qualquer forma. Porem, uma observacao…

Se seu codigo tem uma “porrada” de variaveis estaticas, seu projeto nao estah completamente OO. Um design OO limpo gera poucos - as vezes, nenhum -membros estaticos. Revise o modelo das suas classes nesse respeito, independente da solucao final que adotar.

Luca,

Estendendo a estrutura ortogonal baseada em AOP existente no genesis, eh possivel usar qualquer outro metodo de invocacao do servidor. O genesis possui, out-of-the-box, tres modelos de execucao dos componentes de negocio: local, remoto com EJB e local com EJB. Basta estender um aspecto base, configura-lo no aop.xml e mudar o funcionamento do aplicativo. A documentacao dos aspectos fala mais sobre isso.

Olá

Sou conhecido aqui no GUJ como o homem que não acredita em sistemas confinados na rede local. Só a opção remoto com EJB me despertou o interesse. Mesmo assim com a restrição de que EJBs criam vínculos entre cliente, servidor e EJB engine (que depende do vendor).

Se um dia aparecer um louco na equipe do genesis que crie mais opções remotas usando XML-RPC, SOAP e REST, me interessarei mais ainda.

[]s
Luca

[quote=Luca]Se um dia aparecer um louco na equipe do genesis que crie mais opções remotas usando XML-RPC, SOAP e REST, me interessarei mais ainda.
[/quote]

Esta nos planos para a versao 4. Assim que terminarmos a versao 3.0, pretendo atualizar o roadmap.

Explicando a “porrada”:

Temos um determinado documento (não vou entrar em detalhes). Este documento pode ser de 3 tipos distintos e, além disto, possui dois estados. Para melhorar a codificação, existe (exemplo) uma variável Document.OK, Document.NOT_OK, que auxilia à puxar estes dados do BD.

Dentro deste documento existem, no mínimo, 100 objetos que (exemplo novamente) possuem uma série de características e são os principais do sistema. Cada um destes objetos possuí outros objetos (existe até um objeto que só armazena uma String, mas que a sua validação é essencial) e por aí vaí. Para identificar os tipos de toda essa bagunça usamos essa “porrada” de variáveis. Existem pouqíssimas classes abstratas no projeto, e as que existem nem são persistidas. Eu, pelo menos, acho muito mais simples chegar à alguma conclusão tendo um Document.OK, DocumentLine.EMPTY e por aí vai… acho mais claro… mas por favor me contestem…

Tá meio bagunçado e difícil de voltar atrás, nem sou o pai exatamente da coisa, mas se vocês pudessem ver até achariam que não foi uma má idéia tendo em vista a complexidade da coisa.

Desculpe não ter nem pensado em ver o Project Team… :oops:

Mister_m, quais empecílios teria em utilizar o Genesis nesta minha situação? Pelo que você disse, nenhum, certo?

Só complementando, são todas variáveis final, NUNCA irei alterar…

Acho que isso que vocês deviam estar pensando né… NUNCA ocorrerá de meu servidor e meu objeto serializado no cliente tratarem valores diferentes, serão sempre os mesmo…