Aplicação MultiThread

6 respostas
mcampelo

Pessoal,

estou desenvolvendo uma aplicação MultiThread que vai receber um número muito grande de requests. É uma aplicação StandAlone.

Gostaria de ir criando as novas Threads a medida que o número de requests em paralelo fossem aumentando.

Não consigo imaginar nenhuma maneira simples de fazer isso.

Há algum pattern a ser seguido?

Abraços,

6 Respostas

cv1

Criar uma thread por request pode ser meio pesado… mas eh o jeito mais facil de fazer: use um ServerSocket que, quando pinta uma conexao nova, dispara uma thread pra processa-la e continua a aceitar mais conexoes.

mcampelo

E o modelo dos Application Server? Como funciona?

Tentei dar uma olhda no fonte do Tomcat, mas não encontrei nada.

louds

Usando sockets com java.io o modelo mais escalavel de servidor é usando 1 listening thread e um pool de worker threads. Escalabilidade pequena, performance razoavel. Da uma olhada no util.concurrent (google com I feel lucky) para implementações de todas primitivas necessarias.

Entretanto se a aplicação vai receber muitas requisições e vc precisa de maior escalabilidade vai precisar usar java.nio com sockets não blocantes.
É um modelo bem mais complexo para se trabalhar, usar sockets não blocantes exige bastante book-keeping por parte da aplicação. Performance boa e escalabilidade legal.

Finalmente, se sua aplicação exige escalabilidade monstro e maximizar o throughput do servidor. A única alternativa é usar JNI para ter acesso aos modelos de IO mais performáticos do seu SO, como Overlapped Sockets ou IOCP no win2k; SIGIO ou /dev/pool no linux 2.4; SIGIO, AIO ou epool no linux 2.6; SIGIO, AIO ou kqueue no FreeBSD e SIGIO ou AIO no solaris (acho que tem algo semelhante ao /dev/pool). Todos esses modelos tem algumas coisas em comum: são muito dificeis de usar, io assíncrono é dificil de entender, além de terem performance e escalabilidade incríveis.

O tomcat usa somente a opção 1, os containers j2ee usam uma mistura das 3.

Minha dica é vc verificar a necessidade de escalabilidade da sua aplicação para escolher entre o modelo 1 e 2. São bem diferentes e portar o código entre eles é uma tarefa extremamente chata, com io não blocante um read() pode retornar tendo lido menos bytes que o requisitado.

A opção 3 deve ser escolhida se e somente se vc tiver requisitos de performance gigantescos.

Como parametros vc pode tomar esses valores para um dual p4, 2gb ram:

Sockets blocantes com 1 worker por requisição, começa sofrer nas 40 requisições simultaneas, passou das 100 vira uma carroça.

Sockets não blocantes com multiplexação (java.nio), escala bem ate 200-300 conecções simultaneas dependendo de como o processamento for implementado, mais de 500 o custo de multiplexação passa a ser muito alto.

Usando IO assíncrono da para suportar ate 2000-4000 conecções simultaneas dependendo do SO.

cv1

No fim das contas, sai mais barato usar um bom load balancer e um cache distribuido do que tentar se matar pra implementar um negocio desses na mao. IBM, BEA e Oracle tentam ate hoje acertar a mao no codigo de IO assincrono usando catacteristicas do sistema operacional, e se eles ainda nao acertaram a mao ate agora, pode ter certeza que o que o louds disse foi bem gentil sobre ser um inferno de implementar :smiley:

Ironlynx

Não bloqueantes louds…

louds

Isso depende cv, se as requisições são razoavelmente isoladas umas das outras (http, ftp, EJB) load balancing/clustering funciona muito bem, agora se elas interferirem demais umas com as outras (simuladores de qualquer tipo) conseguir uma performance aceitavel com isso que voce sugeriu pode ser uma tarefa heculeana.

Um cache distribuido não adiantaria para um sistema onde todos os membros alteram constantemente muito dos dados.

Criado 30 de janeiro de 2004
Ultima resposta 31 de jan. de 2004
Respostas 6
Participantes 4