ServiceLocator para sistemas distribuídos

Aos que trabalham com sistemas realmente distribuídos em diferentes instâncias (Seja física ou logicamente).

Como vocês trabalham com o ServiceLocator, ou mesmo com um sistema de configuração dos contextos remotos?

Explico. Imagine um grande sistema com duas ou mais instâncias de um container rodando. Cada uma dessas instâncias contém serviços EJBs que se conversam entre si, remotamente.

Uma das abordagens é configurar no JAR um jndi.properties, que o InitContext dá conta de ler e usar as configurações.

Mas imagine o caso de diferentes EJBs em diferentes instâncias. Como vocês resolvem isso?

Tenho pensado em um ServiceLocator que lê as configurações de cada serviço de um repositório de configurações, e ele se incube de achar os serviços EJB distribuídos.

Para acessar um EJB eu faria:

MeuEJB ejb = (MeuEJ) ServiceLocator.getInstance("CADASTRO").getEjb("nomeJNDI"); UmRelatorioEJB relEjb = (UmRelatorioEJB) ServiceLocator.getInstance("RELATORIO").getEjb("outroNomeJNDI");

E em um diretório teria:

CADASTRO-jndi.properties
RELATORIO-jndi.properties

O que acham? Sugestões? Experiências passadas?

ps: Usando EBJ 3.0… pena que injection, neste caso, não se aplica.

Que tal pensar que seus EJBs oferecem SERVIÇOS e que os serviços estão catalogados em um REPOSITÓRIO de SERVIÇOS!? A boa-e-velha Arquitetura Orientada a Serviços…

Pode até ser que eu use o conceito de UDDI, implementado, por exemplo, no meu ServiceLocator.
Porém eu NÃO vou usar Web Services.

E outra, eu não terei meia dúzia de serviços (EJBs). Terei uma centena deles. E será inviável ficar registrando cada um deles em um repositório.

Olá Daniel,

Certa vez passei por uma situação parecida com a sua. Para solucionar esse empasse de várias possíveis instâncias e vários EJB podendo estar se comunicando entre si, criamos um repositório(Base de dados) de componentes contendo algumas informações sobre eles, tipo algo simples mesmo, contendo informações sobre qual o sistema, a interface do componente, para que ele era aplicado, etc.

Com certeza terá um esforço significativo no início, mas creio que seja o mais coerente a se fazer.

[]s

Eu falei para vc usar Web Services? :?

Estou pensando na possibilidade de criar uma anotação especialista, para o meu caso. Até achei o projeto Apache Beehive, que parece ser uma solução para mim. Vou estudá-lo.

E como você usaria UDDI sem ser com Web Services? Ao menos todas implementações que eu vi de servidores(jUDDI, UDDI4j) só trabalhavam com/para Web Services.

Vc não conseguiria centralizar toda a configuração dos diversos “caminhos” dos diversos EJBs em um unico lugar, como a solução em banco de dados dada pelo amigo acima?

Com isso o ServiceLocator iria ler esta configuração e disponibilizaria o JNDI correto!

Acho que essa seria a melhor solução pra vc…

Outras soluções:

  • Fazer com que o seu ServiceLocator leia todas as suas instancias?!? Feio!
  • Fazer com que todo o serviço seja replicado nas instancias e que o ServiceLocator seja inteligente a ponto de fazer um controle de carga?!? Bonito e trabalhoso!!!
  • Fazer “hardecodeado” a instancia para cada EJB, fazendo o ServiceLocator, num primeiro estagio, trabalhar como uma AbstractFactory?!? Feio!

É Daniel… acho que num tempo razoavel, com uma arqutetura razoavel, seria colocar todas as configurações em um lugar conhecido e fazer com que o ServiceLocator leia essas informações e lhe retorne o Bean EJB correto!

Bom, esta já é a solução que eu propus. Pena que ela não fica tão transparente, pois tenho EJBs que se comunicam com EJBs que podem estar na mesma instância e/ou em outras. E usar a anotação @EJB, neste caso, não se aplica. Então eu teria de ficar usando o ServiceLocator para fazer lookups em todos os pontos. É trabalhoso.

Exemplo:

MeuEJB (instância A)[code]@Stateless(name=“MeuEJB”)
public class MeuEJBBean implements MeuEJB {
private OutroEJB oejb;
private AqueleEJB aejb;

public MeuEJBBean() {
oejb = ServiceLocator.getInstance(“OUTROS”).getEjb(“OutroEJB”);
aejb = ServiceLocator.getInstance(“AQUELES”).getEjb(“AqueleEJB”);
}

public void executar( parâmetros ) {
double val = oejb.calcular( cod );
aejb.processar( user, val );
}
}[/code]

OutroEJB (instância B)@Stateless(name="OutroEJB") public class OutroEJBBean implements OutroEJB { public double calcular( int cod ) { return... ; } }

AqueleEJB(instância A)@Stateless(name="AqueleEJB") public class AqueleEJBBean implements AqueleEJB { public double processar( User u, double val ) { // processa } }

E o ServiceLocator teria dois arquivos de configurações:
OUTROS-jndi.properties
AQUELES-jndi.properties

Agora imagine isso espalhado por centenas de EJBs.

Eu seguiria pelo LoadBalance das instancias, claro, se isso for possivel no seu projeto!

Não sei se a opção de LoadBalance já existe pronta em algum lugar, mas… Caso não, tente estimar o tempo de contrução de um LoadBalance para EJBs distribuidos e leve aos donos do dinheiro…
Porque ai vc teria algo assim:

  • Um pacote com todos os EJBs
  • Cada instancia atualizada com este pacote (terá um trabalho no suporte de infra para este deploy)
  • Criar um BalanceControl para cada instancia
  • Um service Locator que fará um LoadBalance entre as instancias de BalanceControl escritas

Neste momento não preciso de load balance, tendo em vista que cada grupo de ejbs (ejb module) ficará em uma instância diferente.

O que eu quero, de fato, é simplificar o modo de usar os EJBs (lookup).

E como você usaria UDDI sem ser com Web Services? Ao menos todas implementações que eu vi de servidores(jUDDI, UDDI4j) só trabalhavam com/para Web Services.[/quote]

App-serves mais “gordos” (BEA, Websphere) só trabalham com Web Services (se não estou enganado). Por isso, muitos associam UDDI/repositorio de serviços com Web Services.

Já, o pessoal do JBoss ESB, decidiu utilizar uma implementação mais light.

Ou seja, fazer um BD/cadastro de EJBs é pura reinvenção de roda. :wink:

Ops: faltou a referência (http://labs.jboss.com/wiki/Jbossesb/JAXR)

Vamos dizer que estou usando Oracle AS (OC4J), sem JBoss ESB.

Aí já virou consultoria…:wink:

É que o pessoal aqui no GUJ tem mania de sugerir soluções que não se aplicam no “mundo real” dos projetos (++eu).

Só disse que no meu caso (Oracle solution), suas sugestões não vão se encaixar, Taz. Por isso perguntei de casos reais (experiências aplicadas).

Destro, isso existe no Oracle AS tb, mas acho que é um produto a parte. O componente chama-se Oracle Service Registry. Não conheço afundo, mas acredito que não faça exatamente o que vc quer, pois até onde sei ele utiliza SEMPRE o stack SOAP para fazer o registro dos serviços.

[quote=danieldestro]É que o pessoal aqui no GUJ tem mania de sugerir soluções que não se aplicam no “mundo real” dos projetos (++eu).
[/quote]

Isso acontece em qualquer lugar. Mas tb existem pessoas pragmáticas por aqui.

E também tem aquelas que têm que seguir as regras do jogo que os outros definem.

Hmm, é verdade. Mas vc pode seguir as regras definidas por outros e ser pragmático (sem chamar muito atenção :)). O que outros definem não tem nada a ver com o que vc pensa. Por outro lado, entendo que a politicagem atrapalha a maioria dos projetos.

Pq vcs escolheram a Oracle?

Cheguei no meio da história! Já estava aqui.
Tem gente/empresas que gostam de confiar em um nome.