Pular para o conteúdo principal

Enterprise Java no Ambiente de Produção

A variedade de opções da madura plataforma Java em conjunto com a vasta gama de softwares abertos, livres e grátis de propósito específico, muitas vezes torna confuso o processo de seleção do que usar para atender a demanda do seu ambiente Java de produção. Essa responsabilidade pontual deve ser atribuída ao "Arquiteto de Sistemas", que em conjunto com demais "Adminstradores de Sistemas" devem elencar opções e realizar pilotos para avaliar o que se aplica ou não.

A idéia desse post é fornecer um caminho básico nesse processo. Para tanto, vamos analisar os requisitos de um determinado cenário:

  • Aplicação baseada em Web e HTTP
  • Alta demanda, com possibilidade de 60 requisições por segundo em determinados períodos
  • Tempo de resposta de meio segundo ou menos
  • Uma única requisição pode disparar múltiplos cálculos que podem ser realizados em paralelo para diminuir o tempo de resposta
  • Alta disponibilidade
  • Possibilidade de substituir a aplicação sem parar de atender requisições
  • Uso de hardware commodity

Algumas máximas antes de iniciar esse processo:

  • Tecnologia como consequência da solução, e não o que está na moda
  • Estabilidade e confiabilidade: o que os grandes usam?
  • Aberto, livre, grátis!
  • Filosofia UNIX: faça apenas uma coisa, faça bem e possibilite integração
  • Simplicidade de configuração
  • Manutenção simplificada e automatizada
Quais componentes de software identificamos inicialmente? E quais são as escolhas perante os requisitos não funcionais apresentados antes?

Balanceador de carga


O caminho para a escalabilidade é o particionamento de recursos(IO, memória, CPU). Para essa solução selecionaremos um software balanceador de carga bem conhecido da comunidade: haproxy. O haproxy é um pequeno gigante, capaz de escalar absurdamente em ambiente commodity usando IO assíncrona. Possibilita graceful shutdown/startup, sticky sessions, restart sem perda de requisições. Atende o uso de conexões HTTP e TCP. E ainda possui suporte a disaster recovery sites. Você consegue empilhar o balanceamento criando partições em seu cluster, inclusive direcionando tráfego mais prioritário para um parque de servidores mais "nobre" em recursos. Enfim, um produto completo de balanceamento de carga. Outras soluções proprietárias são distribuídas em forma de appliances fechados, com custos em torno de dezenas de milhares de dólares e com suporte limitado de funcionalidades. O haproxy vem com essas e outras funcionalidades já disponíveis, bastando apenas ativá-las via configuração. Em seu portifólio existem sites de altíssima demanda.

inicia o haproxy em modo daemon com nohup
./haproxy -f haproxy.conf -D -q


Reinicia o haproxy a quente, sem perder requisições.
Para tanto é necessário obter o PID do haproxy atual
./haproxy -f haproxy.conf -D -q -sf `ps ax | grep 'haproxy\.conf' | awk '{print $1}'`


Configuração do haproxy: haproxy.conf
# faz o balancedor escutar na 8181
listen http_proxy *:8181
mode http
# requisicoes serao enviadas sempre para a 8181
dispatch localhost:8181
balance roundrobin
# configura um redirecionamento para um servidor qualquer na 8080
# verifica se o servidor está ok a cada 2 segundos. 
# na primeira falha tira ele do pool, após isso ao primeiro ok recoloca ele
server node01 localhost:8080 check inter 2000 rise 1 fall 1
server node02 localhost:8081 check inter 2000 rise 1 fall 1
# other app servers here...
# tenta a conexão por cinco vezes antes de uma nova tentativa
retries 5
# usa um proximo servidor do pool se necessário
redispatch

Servidor de aplicação

Nessa área a escolha é mais difícil, dada a quantidade de ofertas de servidores de aplicação JavaEE, com excelentes candidatos. Porém, se analisarmos os requisitos, fica fácil determinar qual é a opção: Jetty. Lembre-se que precisamos apenas de processamento web, velocidade(IO assíncrona, ou no mundo Java, NIO), simplicidade de configuração, transações locais(JTA possui aplicabilidade em ambientes heterogêneos e existe um alto custo de performance a ser pago com transações XA), simplicidade de conexão e um servidor que sobe em menos de um segundo! Existe ainda a possibilidade de integrar outros componentes ao servidor, como o suporte a sessões web clusterizadas Terracotta conforme configuração simples disponível no wiki do Jetty. Para subir mais servidores basta clonar o diretório! Isso mesmo!

Inicia o jetty
java -jar start.jar etc/jetty.xml

Para o jetty graceful
kill -TERM pid #onde o pid deve ser obtido via ps

Parte do arquivo de configuração do Jetty referente ao pool de threads do container
<Configure id="Server" class="org.mortbay.jetty.Server"> 
<Set name="ThreadPool"> 
<New class="org.mortbay.thread.QueuedThreadPool"> 
<Set name="maxThreads">1000</Set>  
</New>
</Set>
</Configure>

Ou configuração embutida do Jetty via Java
// Escuta na porta 8080
Server server = new Server(8080); 
// Configura a aplicação root(principal)
Context root = new Context(server,"/",Context.SESSIONS); 
// Configura uma servlet(HelloServlet), mapeando sua url como /*
root.addServlet(new ServletHolder(new HelloServlet("Ciao")), "/*"); 
// inicia o servidor
server.start(); 

Datasource

Muito se fala em outras formas de armazenamento de informações, como o modelo chave/valor, schemaless e outros tipos de NoSQL. Porém sabemos que a realidade no desenvolvimento de aplicações corporativas vai continuar por um bom tempo sendo o bom, velho e eficiente RDBMS. Não somente por motivos de integração com dados legados, mas também pela beleza de armazenar informações com estrutura bem definida. Você imagina sua camada de domínio como uma bagunça? Lembre que "Domínio"(schema) é diferente de "Documento"(sem schema, ou schemaless)! Independente de sua estratégia de persistência, use um pool de conexões disponibilizado ou recomendado pelo fornecedor do seu banco de dados. Os grandes vendors já possuem connection pool próprio, muitas vezes distribuído com o próprio driver JDBC.

Configurando do pooling datasource
Jdbc3PoolingDataSource source = new Jdbc3PoolingDataSource();
source.setDataSourceName("A Data source");
source.setServerName("localhost");
source.setDatabaseName("test");
source.setUser("testuser");
source.setPassword("testpassword");
source.setMaxConnections(1000);
// usando uma conexão lógica do pool
Connection con = source.getConnection();

Processamento paralelo

Aqui a estratégia depende do cenário. Hoje as máquinas possuem vários cores e o suporte SMP já está disponível em várias JVMs e sistemas operacionais há um bom tempo. Vamos usar então vários cores! O paradigma Master/Worker funciona de forma simples: dispare várias unidades de processamento, realize a agregação dos resultados e depois se necessário repita o processo. A API java.util.concurrent fornece Executors para processamento de Runnables paralelos e suporte a agregação via CountDownLatch(apenas uma das possibilidades) e armazenamento de resultados sem necessidade de sincronização, usando um ConcurrentHashMap. Se você quer evitar problemas com compartilhamento de estado e necessita de maior performance devido a uma demanda maior ainda(absurda), pode optar por integrar erlang e usar um modelo de programação 100% assíncrono e com estado totalmente distribuído.

Exemplo de código usando API concurrent do Java
// cria um threadpool com threads reutilizáveis
Executor e = Executors.newCachedThreadPool();
// cria um latch de tamanho 10
final CountDownLatch latch = new CountDownLatch(10);
final Random r = new Random();
for (int i = 0; i < 10; i++) {
// executa uma thread
e.execute(new Runnable() {
public void run() {
try {
System.out.println("mapping...");
// random sleep
try {
Thread.sleep(r.nextInt(5000));
} catch (InterruptedException e) {}
}
finally {
// diminui 1 do latch
latch.countDown();
}
}
});
}

// realiza a espera até que o latch atinja zero
try {
latch.await();
} catch (InterruptedException e1) {}

// esse código sempre será executado apenas após todas as threads concluirem!
System.out.println("reducing...");
System.exit(0);

Cache

Você usa RDBMS e sabe que o banco de dados vai ser o gargalo, pois particionar a camada de aplicação horizontalmente é trivial, basta clonar servidores de aplicação, adicionar uma linha de configuração ao balanceador e pronto! Como fazer então para diminuir o tempo de resposta, evitando IO e processamento ao recuperar seus registros? Guarde-os na memória! Informações imutáveis podem inclusive residir na memória por tempo indeterminado, sem necessidade de expiração. Informações mutáveis que são acessadas frequentemente devem ser guardadas em cache e atualizadas sempre que forem persistidas. Em casos simples, prefira acesso direto a um cache de segundo nível(fora do servidor de aplicação, conhecido também por cache de rede, compartilhado por uma partição específica do cluster ou por todo ele) e uso de muita memória, que é recurso barato já há algum tempo. Em ambientes maiores pode-se usar um cache de primeiro nível dentro da VM, ou mesmo particionamento de caches. Seguindo o mesmo padrão de escolhas temos o memcached. É um cache de rede genérico(guarde objetos Java serializáveis, strings, etc) usado pelos sites de maior demanda na web. Suporta expiração e possui performance como funcionalidade principal. Sua API de acesso Java é fornecida pelo fabricante, porém possui outras opções.

Iniciando o memcached como daemon na porta 40122 usando 3GB de memória
./memcached -u usr -d -m 3072 -l localhost -p 40122
Client memcached Java
// cria um client para o memcached
MemCachedClient mcc = new MemCachedClient();
// obtem uma conexao ao connection pool do Memcached
SockIOPool pool = SockIOPool.getInstance();
// configura nosso servidor
pool.setServers( new String[] {  "localhost:40122" } );
// inicializa o pool
pool.initialize();
// grava no memcached uma chave "foo" com um valor qualquer
mcc.set( "foo", "This is a test String" );
// recupera do memcached o valor da chave "foo"
String bar = mcc.get( "foo" );

Cluster

Como compartilhar estado entre os servidores de aplicação de forma rápida, permitindo que um servidor possa ser substituído sem que a sessão do usuário caia? Como fazer isso facilmente e de forma transparente, sem alterar código, apenas via configuração? O Jetty possui suporte ao Terracotta fornecido como um extra, simples de ser configurado. Configuração do terracotta para suporte a sessões clusterizadas no Jetty tc-config.xml
<?xml version="1.0" encoding="UTF-8"?><tc:tc-config xmlns:tc="http://www.terracotta.org/config"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.terracotta.org/config http://www.terracotta.org/schema/terracotta-4.xsd"><servers><!-- configura um servidor Terracotta -->
<server host="localhost"/>
</servers>
<clients>
<modules>
<!-- carrega o módulo de integração com o Jetty -->
<module name="tim-jetty-6.1" version="2.0.0" />
</modules>
</clients>
<application>
<dso>
<instrumented-classes>
<include>
<!-- permite qualquer classe ser armazenada no cluster
há necessidade de fazer fine-tuning disso, 
pois o Terracotta instrumenta classes incluidas, 
o que pode gerar um custo de tempo em runtime 
inaceitável!-->
<class-expression>..*</class-expression>
</include>
</instrumented-classes>
</dso>
</application>
</tc:tc-config>
Configuração do Jetty para integrar o Terracotta jetty-terracotta.xml
<Configure id="Server" class="org.mortbay.jetty.Server">
<New id="tcIdManager" class="org.mortbay.terracotta.servlet.TerracottaSessionIdManager">
<Arg>
<Ref id="Server" />
</Arg>
<Set name="workerName">
<SystemProperty name="jetty.node" default="node1" />
</Set>
</New>
<Call name="setAttribute">
<Arg>tcIdManager</Arg>
<Arg><Ref id="tcIdManager" /></Arg>
</Call>
</Configure>
Arquivo de configuração do contexto de sua aplicação
<Configure class="org.mortbay.jetty.webapp.WebAppContext">
...
<Property name="Server" id="Server">
<Call id="tcIdManager" name="getAttribute">
<Arg>tcIdManager</Arg>
</Call>
</Property>
<Set name="sessionHandler">
<New class="org.mortbay.terracotta.servlet.TerracottaSessionHandler">
<Arg>
<New class="org.mortbay.terracotta.servlet.TerracottaSessionManager">
<Set name="idManager">
<Ref id="tcIdManager" />
</Set>
</New>
</Arg>
</New>
</Set>
...
</Configure>
Inicie o Jetty (onde TC_HOME é o diretório onde está instalado o Terracotta)
$TC_HOME/bin/dso-java.sh -Dtc.config=tc-config.xml -jar start.jar etc/jetty.xml etc/jetty-terracotta.xml
Quais são as qualidades adicionais? Redundância? Automatização? Como realizar diagnóstico de problemas e ações corretivas? Como atualizar a aplicação a quente sem perda de requisições? Testes? Não perca a parte dois desse post, onde vamos analisar essas situações e fornecer caminhos e alternativas de software para cobrir esses casos. Quer saber mais a respeito desse assunto? Então não perca o CEJUG Tech Day 2009, realizado pelo CEJUG em conjunto com a FANOR - Faculdades Nordeste! Eu estarei falando sobre como gerenciar um ambiente de produção Java de configuração semelhante. Teremos outros ilustres palestrantes, dentre eles o Simon Ritter falando sobre as novidades da JDK 7. Vejo vocês no CEJUG Tech Day 2009, até lá! :)

Abs,
JV -- julioviegas.com

Comentários

Unknown disse…
Cara, você é um monstro!!!!

Demais este post, simplesmente demais.

Parabéns!
Yara Senger disse…
Este evento realmente promete. Até eu fiquei com agua na boca de participar. Não somente pela localização, mas também pela amostra da sua palestra e das outras.

Um abraço e bom evento!
Julio Viegas disse…
Yara/Vinicius,

Muito obrigado! ;)

A ideia da apresentação é mesclar estratégia e tecnologia. Acho que é um assunto que ninguém explorou ainda de forma integrada. E é algo que ocorre nas empresas, só que ninguém fala...

Eu já estou na expectativa do evento!

Abs
Wagner Santos disse…
Muito massa seu post Julio!!

Só uma dúvida, é confiável utilizar o HAProxy em um ambiente de produção de alta disponibilidade (24 x 7 )?

Abraço,

Postagens mais visitadas deste blog

Você já pensou em ser palestrante em algum evento ?

Você já deve ter participado de algum evento e pensado como deve ser legal ser palestrante... E para falar a verdade, é muito bom mesmo. Eu adoro, o Vinicius adora e conheço muitas pessoas que curtem cada minuto da participação no evento como palestrante. Com certeza é uma responsabilidade a mais. Você sente medo, adrenalina, tem que se preparar. Literalmente coloca a cara a tapa para qualquer pessoa te avaliar em todos os sentidos. Qual o seu tom de voz?  Seus slides são legais? Você manja mesmo ?  Seu português está ok?  E as palavras em inglês ?  Teve algum deslize técnico? E MUITO mais.  Mas é claro que a exposição tem dois lados... e os resultados podem ser ótimos. Normalmente conhecemos mais pessoas como palestrantes e podem surgir boas oportunidades de negócio. É sempre positivo ter uma nova referência positiva quando as pessoas buscam nosso nome no Google, podemos fazer a diferença para quem está assistindo a palestra e muito mais.  No The Developer's

TDC INNOVATION lança University Pass

Modalidade de ingresso tem como objetivo ajudar na capacitação dos universitários Uma pesquisa realizada em 2020 pela Associação Brasileira das Empresas de Tecnologia da Informação e Comunicação (Brasscom) diz que até o ano de 2024 o Brasil precisará de cerca de 420 mil profissionais na área de Tecnologia da Informação. Porém, por ano, a mesma pesquisa diz que o país forma apenas 46 mil profissionais capacitados no nicho. Pensando nisso, para ajudar na formação e capacitação desses jovens profissionais, o TDC INNOVATION, segunda edição do ano do The Developer's Conference, lança o University Pass, modalidade de ingresso que possibilita aceso digital gratuito a todas as palestras do evento, ou com 50% de desconto para quem preferir ir pessoalmente. Com o tema central “Desafios para a criação do futuro Digital”, o TDC INNOVATION ocorrerá entre 1 e 3 de junho, de forma híbrida: presencialmente no Centro de Convenções CentroSul, em Florianópolis, e com transmissão simultaneamente pela

TDC ONLINE: SUA PLATAFORMA DE PALESTRAS GRAVADAS DO TDC DISPONÍVEL

Além do conteúdo ao vivo transmitido online nas edições do TDC, agora você pode ter acesso à centenas de palestras gravadas, através da nossa nova plataforma de vídeos - o TDC Online, que reúne todas as Trilhas premium, Stadium e Salas dos Patrocinadores das edições anteriores de 2022, TDC Innovation e TDC Connections.  Para acessar, basta clicar na edição em que você participou ( TDC Innovation ou TDC Connections ); Fazer o mesmo login (com e-mail e senha) cadastrados na hora de adquirir ou resgatar o seu ingresso no TDC; E clicar na Trilha de sua opção, e de acordo com a modalidade do seu ingresso. Logo em seguida, você será direcionado para a seguinte página com a lista de todas as palestras por Trilha: Pronto! Agora você tem acesso à centenas de palestras gravadas da sua área de interesse, para assistir como e quando quiser! Caso tenha esquecido a senha, clique na opção "Esqueci a senha" , insira o e-mail que você realizou para o cadastro no evento, e aparecerá a op

Entendendo como funciona a programação de computadores: linguagens de programação, lógica, banco de dados

Nesse post, diferente dos últimos que foram mais enfáticos nas experiências com tecnologias, vou focar um pouco mais nos profissionais que estão começando, ou pretendem ingressar na área de desenvolvimento de software, falando sobre conceitos fundamentais relacionados a programação em geral . Mercado de trabalho para programação Conforme já sabemos, o mercado de desenvolvimento de software, especialmente no Brasil, continua em franca expansão, sendo que cada vez mais as empresas buscam desenvolver seus próprios sistemas usando as mais diferentes e novas tecnologias. Algumas matérias interessantes: As seis profissões mais valorizadas em 2010 no IDG Now! Muitas vagas e sensação de reaquecimento da economia Por isso, a área de desenvolvimento de software tem despertado interesse em muitos profissionais de outras áreas que desejam mudar de profissão, já que as oportunidades de trabalho tendem a ser maiores. Esse é um perfil presente em muitos dos clientes da Globalcode que acabou m

Segurança da informação no alvo: o que esperar do futuro?

A segurança da informação não se trata apenas de proteger os dados contra acesso não autorizado. Na prática, refere-se aos recursos que impedem: uso; registro; inspeção; divulgação; interrupção; modificação; destruição de dados. O uso de dados pode abranger desde um perfil nas redes sociais a detalhes financeiros, biometrias ou novos projetos. Por isso, a preocupação com a proteção dos dados é crescente, tanto para empresas quanto clientes. Para muitas pessoas, a coleta de dados é considerada invasão de privacidade, criando desconfiança do titular dos dados, pois o uso dos dados pode ser facilmente corrompido, utilizado para fins não declarados. Apesar de o uso dos dados terem impulsionado os avanços tecnológicos na última década, as organizações lidam com o desafio de distinguir dados de informações pessoais de modo a proteger a privacidade e as preferências dos clientes. Neste artigo, abordaremos o impacto da segurança da informação e o que esperar do futuro. Confira casos conhecido

TDC Digital: o que você precisa saber para transformar sua carreira em 2022

O TDC Digital é o maior evento de TI do mercado e proporciona crescimento profissional a partir de palestras com especialistas e oportunidades de networking com o mundo todo, direto da sua casa. Através da escolha individual de cada participante é possível obter experiências imersivas e transformadoras conforme o tema-chave de cada trilha.  O evento também é o lugar ideal para ajudar no desenvolvimento de carreiras, permitindo que qualquer pessoa com vontade — e um tema interessante — seja palestrante e compartilhe suas experiências e conhecimentos. Para aqueles que querem  participar como ouvinte a plataforma do TDC favorece conferências dinâmicas, e o encontro de diversas comunidades e ecossistemas de TI. E, após a escolha de uma trilha, fica mais fácil acompanhar especialistas para aprender e se inspirar. Em 2021, o The Developer’s Conference (TDC) foi 100% digital e, em três dias de evento, contou com mais de 300 horas de conteúdos , incluindo: Agile; Testes; Design; Web e Mobile;