Seu aplicativo J2EE está lento? Eles podem suportar o aumento do tráfego? Este artigo descreve a tecnologia de otimização de desempenho para o desenvolvimento de páginas JSP e Servlets altamente elásticos e de alto desempenho. A ideia é construir o mais rápido possível e se adaptar ao crescente número de usuários e às suas solicitações. Neste artigo, vou levá-lo a aprender técnicas práticas e comprovadas de ajuste de desempenho que irão melhorar muito o desempenho de seus servlets e páginas jsp, melhorando assim o desempenho do J2EE. Algumas dessas tecnologias são utilizadas em fases de desenvolvimento, como fases de design e codificação. Outra parte da tecnologia está relacionada à configuração.
Técnica 1: Armazenando dados em cache no método HttpServletinit()
O servidor chama o método init() do servlet após criar a instância do servlet e antes que o servlet processe quaisquer solicitações. Este método é chamado apenas uma vez no ciclo de vida do servlet. Para melhorar o desempenho, armazene em cache os dados estáticos em init() ou execute operações caras durante a inicialização. Por exemplo, uma prática recomendada é usar um conjunto de conexões JDBC que implemente a interface javax.sql.DataSource.
DataSource é obtido da árvore JNDI. É muito caro usar JNDI para encontrar o DataSource toda vez que o SQL é chamado e isso afeta seriamente o desempenho do aplicativo. O método init() do Servlet pode ser usado para obter o DataSource e armazená-lo em cache para reutilização posterior:
publicclassControllerServletextendsHttpServlet
{
privatejavax.sql.DataSourcetestDS=null;
publicvoidinit(ServletConfigconfig)throwsServletException
{
super.init(config);
Contextctx=nulo;
tentar
{
ctx=newInitialContext();
testDS=(javax.sql.DataSource)ctx.lookup("jdbc/testDS");
}
catch(NamingException)
{
ne.printStackTrace();
}
pegar (exceção)
{
e.printStackTrace();
}
}
publicjavax.sql.DataSourcegetTestDS()
{
retornotesteDS;
}
...
...
}
Técnica 2: Desative a função de carregamento automático de servlets e JSPs
Você terá que reiniciar o servidor toda vez que modificar o Servlet/JSP. Como o recurso de carregamento automático reduz o tempo de desenvolvimento, esse recurso é considerado muito útil durante a fase de desenvolvimento. No entanto, é muito caro na fase de tempo de execução; o servlet/JSP causa baixo desempenho devido ao carregamento desnecessário e ao aumento da carga no carregador de classes. Novamente, isso pode fazer com que seu aplicativo tenha conflitos estranhos porque as classes que foram carregadas por um determinado carregador de classes não podem cooperar com as classes carregadas pelo carregador de classes atual. Portanto, para obter melhor desempenho no ambiente de execução, desative a função de carregamento automático do servlet/JSP.
Técnica 3: Controlar HttpSession
Muitos aplicativos exigem uma série de solicitações de clientes para que possam ser relacionados entre si. Como o protocolo HTTP não tem estado, os aplicativos baseados na Web precisam ser responsáveis por manter esse estado chamado sessão. Para suportar aplicações que devem manter o estado, a tecnologia Javaservlet fornece APIs que gerenciam sessões e permitem múltiplos mecanismos para implementar sessões. O objeto HttpSession atua como uma sessão, mas há um custo para usá-lo. Sempre que HttpSession for usado e substituído, ele será lido pelo servlet. Você pode melhorar o desempenho usando as seguintes técnicas:
lNão crie uma HttpSession padrão na página JSP: Por padrão, a página JSP cria uma HttpSession. Se você não usar HttpSession em sua página JSP, para economizar sobrecarga de desempenho, use as instruções da página a seguir para evitar a criação automática de objetos HttpSession:
< %@pagesession="false"% >
1) Não armazene gráficos de objetos grandes em HttpSession: Se você armazenar dados em HttpSession como um gráfico de objeto grande, o servidor de aplicativos terá que processar todo o objeto HttpSession a cada vez. Isso forçará a serialização Java e aumentará a sobrecarga computacional. Devido à sobrecarga da serialização, a taxa de transferência do sistema diminuirá à medida que os objetos de dados armazenados no objeto HttpSession aumentarem.
2) Libere o HttpSession após o uso: Quando o HttpSession não estiver mais em uso, use o método HttpSession.invalidate() para invalidar a sessão.
3) Defina o valor de tempo limite: um mecanismo de servlet possui um valor de tempo limite padrão. Se você não excluir a sessão ou continuar usando a sessão até atingir o tempo limite, o mecanismo do servlet excluirá a sessão da memória. Devido à sobrecarga na memória e na coleta de lixo, quanto maior o valor do tempo limite da sessão, maior será o seu impacto na resiliência e no desempenho do sistema. Tente definir o valor do tempo limite da sessão o mais baixo possível.
Técnica 4: Use a compactação gzip
A compactação é a prática de remover informações redundantes e descrevê-las no menor espaço possível. Usar gzip (GNUzip) para compactar documentos pode reduzir efetivamente o tempo de download de arquivos HTML. Quanto menores forem suas mensagens, mais rápido elas serão enviadas. Portanto, se você compactar o conteúdo gerado pela sua aplicação web, mais rápido ele chegará ao usuário e será exibido na tela do usuário. Nem todo navegador oferece suporte à compactação gzip, mas é fácil verificar se um navegador oferece suporte e enviar conteúdo compactado gzip para o navegador. O trecho de código abaixo ilustra como enviar conteúdo compactado.
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)
throwsIOException,ServletException
{
OutputStreamout=null
//Verifique o cabeçalho de codificação de aceitação da solicitação HTTP.
//Se o cabeçalho incluir gzip, escolha GZIP.
//Se o cabeçalho incluir compactação, escolha ZIP.
//Caso contrário,
escolhanocompression.Stringencoding=request.getHeader("Accept-Encoding");
if(encoding!=null&&encoding.indexOf("gzip")!=-1)
{
response.setHeader("Codificação de conteúdo","gzip");
out=newGZIPOutputStream(response.getOutputStream());
}
elseif(encoding!=null&&encoding.indexOf("comprimir")!=-1)
{
response.setHeader("Codificação de conteúdo","comprimir");
out=newZIPOutputStream(response.getOutputStream());
}
outro
{
out=response.getOutputStream()
;
...
...
}
Técnica 5: Não use SingleThreadModel
SingleThreadModel garante que o servlet manipule apenas uma solicitação por vez. Se um servlet implementar essa interface, o mecanismo do servlet criará uma instância de servlet separada para cada nova solicitação, o que causará muita sobrecarga no sistema. Se você precisar resolver problemas de segurança de thread, use outros métodos em vez desta interface. O uso de SingleThreadModel não é mais recomendado no Servlet2.4.
Técnica 6: Use o
mecanismo de servlet do pool de threads para criar um thread separado para cada solicitação, atribua o thread ao método service() e exclua o thread após a execução do método service(). Por padrão, o mecanismo do servlet pode criar um novo thread para cada solicitação. Como criar e excluir threads é caro, esse comportamento padrão reduz o desempenho do sistema. Podemos usar o pool de threads para melhorar o desempenho. De acordo com o número esperado de usuários simultâneos, configure um pool de threads e defina o número mínimo e máximo de threads no pool de threads, bem como os valores de crescimento mínimo e máximo. Inicialmente, o mecanismo do servlet cria um conjunto de encadeamentos com um número de encadeamentos igual ao número mínimo de encadeamentos na configuração. O mecanismo de servlet então atribui um thread do pool a uma solicitação em vez de criar um novo thread a cada vez. Depois de concluir a operação, o mecanismo de servlet coloca o thread de volta no pool de threads. Usando pools de threads, o desempenho pode ser significativamente melhorado. Se necessário, mais threads podem ser criados com base no número máximo de threads e no número de crescimento.
Técnica 7: Escolha o mecanismo de inclusão correto
Nas páginas JSP, há duas maneiras de incluir arquivos: incluir instruções (< %@includefile="test.jsp"% >) e incluir ações (<jsp:includepage="test.jsp " flush="verdadeiro"/>). A diretiva include inclui o conteúdo de um arquivo especificado durante a fase de compilação, por exemplo, quando uma página é compilada em um servlet; Uma ação de inclusão envolve a inclusão do conteúdo do arquivo durante a fase de solicitação, por exemplo, quando um usuário solicita uma página. Incluir instruções é mais rápido do que incluir ações. Portanto, a menos que os arquivos incluídos sejam alterados com frequência, você obterá melhor desempenho usando a diretiva include.
Técnica 8: Use escopos apropriados em ações useBean
Uma das maneiras mais poderosas de usar páginas JSP é trabalhar com componentes JavaBean. JavaBeans pode ser incorporado em páginas JSP usando a tag <jsp:useBean>. A sintaxe é a seguinte:
<jsp:useBeanid="name"scope="page|request|session|application"class=
"package.className"type="typeName">
</jsp:useBean>
O atributo scope descreve o escopo visível do bean. O valor padrão do atributo de escopo é página. Você deve escolher o intervalo correto com base nas necessidades do seu aplicativo, caso contrário, isso afetará o desempenho do seu aplicativo.
Por exemplo, se você precisar de um objeto específico para alguma solicitação, mas definir o escopo como sessão, esse objeto permanecerá na memória após o término da solicitação. Ele permanecerá na memória, a menos que você o exclua explicitamente da memória, invalide a sessão ou a sessão expire. Se você não escolher o atributo de escopo correto, o desempenho será afetado devido à sobrecarga de memória e coleta de lixo. Portanto, defina um escopo adequado para os objetos e exclua-os assim que terminar de usá-los.
Técnicas diversas
1) Evite concatenação de strings: Como os objetos String são objetos imutáveis, o uso do operador "+" resultará na criação de um grande número de objetos de tempo zero. Quanto mais "+" você usar, mais objetos de tempo zero serão gerados, o que afetará o desempenho. Quando precisar concatenar strings, use StringBuffer em vez da operação "+".
2) Evite usar System.out.println: System.out.println processa entrada/saída de disco de forma síncrona, o que reduz bastante o rendimento do sistema. Evite usar System.out.println sempre que possível. Embora existam muitas ferramentas de depuração maduras disponíveis, às vezes System.out.println ainda é útil para fins de rastreamento ou depuração. Você deve configurar System.out.println para abri-lo apenas durante as fases de erro e depuração. Usando uma variável finalBoolean, quando configurada como falsa, as verificações de otimização e a saída do rastreamento de execução são concluídas durante a fase de compilação.
3) Comparação de ServletOutputStream e PrintWriter: Devido ao fluxo de saída de caracteres e à codificação de dados em bytes, o uso de PrintWriter apresenta uma pequena sobrecarga de desempenho. Portanto, PrintWriter deve ser usado após todas as conversões de conjuntos de caracteres terem sido feitas corretamente. Por outro lado, quando você sabe que seu servlet retornará apenas dados binários, use ServletOutputStream porque o contêiner do servlet não codifica dados binários, eliminando assim a sobrecarga de conversão do conjunto de caracteres.
Resumo
O objetivo deste artigo é mostrar algumas técnicas práticas e comprovadas de otimização de desempenho para melhorar o desempenho de servlets e JSP, o que melhorará o desempenho geral de seus aplicativos J2EE. A próxima etapa deve ser observar o ajuste de desempenho de outras tecnologias relacionadas, como EJB, JMS e JDBC.