To precisando modelar um sistema de servidores semelhante a figura anexada.
Explicando.
Selector 1 seria um server socket que fica conectado diretamente a internet.
Atravez do selector 1 os clientes irao conectar e precisam enviar arquivos, mas quem vai processar o recebimento destes arquivos seria o server receiver 1 e 2. Meu problema ta sendo em pensar como fazer essa “ponte”, quando o cliente conecta no selector ele “ve” qual server receiver ta disponivel e repassa o controle.
Os server receiver’s nao poderao ficar disponiveis na internet (com ip fixo). Outra caracteristica é que eles podem estar em outra maquina.
Pensei em algumas maneiras de fazer isso, com socket mesmo ou com rmi, mas nao consegui imaginar qual seria a melhor situacao.
Pensando na melhor forma, vc não poderia utilizar JMS ou Message Driven Bean? Isso faz com que tenha um requisição asscicrona.
Já pensando na arquiteura, sem pensar na melhor forma…
Você tera o Selector com IP fixo, então naum poderia fazer os receivers se conectarem “pelo menos nas suas inicializações quando houverem” no selector mandando seus IPs?
Depois poderia ter uma Flag para cada e sempre que o receiver enviar uma requisição para o receiver ele seta esta flag e assim vc sabe quem esta ocupado.
Se quiser que cada um possa controlar mais de um requisição, fazendo com que o selector somente distribua a carga, pode ter um contador para cada receiver e assim pode ficar comparando-os.
Mas pensando na melhor implementação, vc já pensou em utilizar os containers J2EE em cluster, assim vc naum precisa controlar nada e ainda tem mais segurança e talvez até passe a utilizar seu selector como mais um receirver se ele aguentar um container j2ee sei lá.
Gostei bastante da sua pergunta, Posta ai quais novidades, gostaria de poder contribuir mais…
Bela pergunta muito bem formulada com figura e tudo como poucas vezes já vi em um fórum de Java.
E bela resposta também!
Eu, se coubesse no problema, também sugeriria MDB ou simplesmente JMS direto. O ActiveMQ está aí para isso.
Quanto a sugestão de conteiners em cluster também achei muito interessante mas talvez um pouco luxuosa. Na verdade é bem fácil de fazer.
Sem pensar muito chuto que talvez se possa redirecionar com DNS.
Será que não valeria a pena um servletzinho mínimo recebendo por http e repassando já dentro da rede do servidor para o socket?
Não me agrada a idéia de socket aberto na Internet porque amanhã mudam as regras da administração de segurança e a solução fica inviável. Recebendo por http há outras alternativas de desvio usando características do Apache.
Divaguei. Mas meu principal interesse é seguir recebendo notícias da atualização deste tópico.
Já implementei uma solução parecida com Sockets & Threads apenas.
Minha sugestão é ter um serviço principal que aceita conexões TCP assíncronas dos clientes (que é bem simples de se fazer com socket e thread) e que agirá como escalonador do trabalho e proxy.
Os Receivers trabalharão como serviços também e serão invocados pelo servidor principal.
Eu começaria com testes simples antes de incluir servidores J2EE e outras tecnologias na implementação.
Nao entendi bem como eu poderia usar o JMS ou MDB nesse caso. Tem como da uma esplanada melhor?
[quote=btafarelo]Você tera o Selector com IP fixo, então naum poderia fazer os receivers se conectarem “pelo menos nas suas inicializações quando houverem” no selector mandando seus IPs?
Depois poderia ter uma Flag para cada e sempre que o receiver enviar uma requisição para o receiver ele seta esta flag e assim vc sabe quem esta ocupado.
Se quiser que cada um possa controlar mais de um requisição, fazendo com que o selector somente distribua a carga, pode ter um contador para cada receiver e assim pode ficar comparando-os.[/quote]
Estes casos poderao acontecer. Seria quase um LoadBalance porque os receivers poderao processar mais de uma requisicao por vez.
Nao sei ao certo como vai ser esta parte, mas os receivers irao se registrar ao Selector. Até porque o Selector precisa ter a lista de receiver que estao conectado pra saber pra quem direcionar.
Ja pensei, mas nao gostaria de usar essa solucao porque eu dependeria de instalar servidores, configurar cluster, etc.
Ja é o segundo que fala nesta solucao, vou dar uma pesquisada a respeito.
Pensei nessa solucao tambem, mas como seria pra um produto nao gostaria de depender desse tipo de configuracao, mas se nao tiver solucao teria que olhar melhor.
Será que não valeria a pena um servletzinho mínimo recebendo por http e repassando já dentro da rede do servidor para o socket?
Belo ponto levantado Luca, nao tinha pensado nisso. Mas sera um problema grande? Fiquei na duvida agora.
[quote=s4nchez]Minha sugestão é ter um serviço principal que aceita conexões TCP assíncronas dos clientes (que é bem simples de se fazer com socket e thread) e que agirá como escalonador do trabalho e proxy.
Os Receivers trabalharão como serviços também e serão invocados pelo servidor principal.[/quote]
Foi por aqui que comecei minha ideia. Como eu ja fiz servidorzinho multiplexado com NIO pensei fazer uma chamada remota aos Receivers e passar o SocketChannel. Minha duvida ficou se nao daria problema com o SocketChannel ja que a conexao iniciou em uma maquina e eu estaria transferindo esse SocketChannel para outra maquina com outro ip.
Se eu usar Socket meu maior problema até agora é fazer o repasse deste SocketChannel para o Receiver sem que o Selector tenha que pocessar algo.
Ficaria como na figura, e quando a chamada remota fosse feita eu passaria o SocketChannel pro Receiver por parametro.
Eu nao conhecia este software. Dei uma pesquisada rapida e pude perceber que ele é pra Unix correto?
Pra mim isso é um problema, como estou modelando esse servidor pra um produto tenho algumas restricoes. Primeiro a intencao é ser em Java para ser multiplataforma. Outra seria que nao posso usar produtos de terceiros que eu nao tenha certeza de continuidade, fontes, etc.
Vou dar mais uma olhada pra nao tirar conclusoes precipitadas, mas acho que nao vai dar pra usar ele.
Se eu estiver errado, alguém por favor me corrija, mas eu acredito que não é possível passar o channel remotamente, porque a sessão de transporte já estaria estabelecida entre o cliente e o front-end. Se você se preocupa com o front-end se tornar um gargalo ou SPOF, daria para pensar em uma solução no nível de protocolo de aplicação para encaminhar uma sessão para um back-end escolhido na hora, mas estes precisariam ter interfaces na rede pública também.
[quote=AllMighty][quote=fabgp2001]
Se eu usar Socket meu maior problema até agora é fazer o repasse deste SocketChannel para o Receiver sem que o Selector tenha que pocessar algo.
[/quote]
Se eu estiver errado, alguém por favor me corrija, mas eu acredito que não é possível passar o channel remotamente, porque a sessão de transporte já estaria estabelecida entre o cliente e o front-end. Se você se preocupa com o front-end se tornar um gargalo ou SPOF, daria para pensar em uma solução no nível de protocolo de aplicação para encaminhar uma sessão para um back-end escolhido na hora, mas estes precisariam ter interfaces na rede pública também.[/quote]
Olá,
Pois é eu tambem acho que nao daria pra fazer isso, mas como até agora nao achei nenhum lugar afirmando isso vou ter que testar e comprovar.
Se nao der pra fazer assim acho que o bixo vai pegar :S
[quote=s4nchez]Acredito que se não for possível fazer diretamente, ainda tem como resolver com um esquema de tunneling controlado pelo Selector mesmo.
Ele ficaria responsável em estabelecer as conexões e ajustar os input/output streams entre as máquinas, agindo como um proxy :)[/quote]
Deixa eu ver se entendi.
Tu diz fazer o seguinte: Selector recebe uma conexao externa, nesse momento o Selector abre uma conexao interna com um Receiver e fica repassando o que recebe do cliente?
Sim, a idéia é essa. Mas acredito que o Selector não precisa ficar repassando byte a byte. Talvez só redirecionando o inputstream do cliente para um outputstream que o Receiver vai ler já é suficiente.
[quote=s4nchez]Sim, a idéia é essa. Mas acredito que o Selector não precisa ficar repassando byte a byte. Talvez só redirecionando o inputstream do cliente para um outputstream que o Receiver vai ler já é suficiente.
Só isso já atenderia sua necessidade?[/quote]
Por enquanto atende sim.
Quando tu comentou acima sob essa solucao foi o que imaginei passar o InputStream ou ainda como estou usando NIO um ByteBuffer.
O unico detalhe é que pra mim tudo isso é teoria entao so testando pra ver se funciona.
Bom vou fazer uns testes e posto aqui depois o que saio de solucao.
Se alguem tiver algo mais a acrescentar sera bem vindo
[quote=fabgp2001] Quando tu comentou acima sob essa solucao foi o que imaginei passar o InputStream ou ainda como estou usando NIO um ByteBuffer.
]['s[/quote]
se não me engano não rola de passar o objeto InputStream pq ele não é serializavel… lembro de tentar uma vez enão funcionar, tinha que ler e ir passando os bytes, mas não tenho certeza.
Será que não ficaria melhor com um PipedInputStream? Neste caso você não teria que ler nada do cliente, já que toda informação que entrar por este input stream será encaminhada diretamente para o output stream do receiver.
Andei dando uma olhada neste PipedInputStream pelo que notei se usar ele eu usaria metodo remoto no acesso do Selector ao Receiver e nao conexao Socket. Seria isso?
Eu acho mais provável que esse código seja IO-bound do que CPU-bound. Usando IO bloqueante, a chamada a selectorSocket.read(buf) só retorna ao encher o buffer.
Não entendi bem como isso funcionaria, vc pega uma InputStream do server socket e depois como passa isso para a PipedInputStream? AFAIK, ela não é um decorator tipo a BufferedInputStream.