Estou desenvolvendo uma apicação dentro do tomcat6.
Sendo que, eu recebe várias requisições através de uma servlet que é chamada por um outro pc.
Esta servlet recebe uns parâmetros via GET e guarda os mesmos em um arquivo, ela abre e fecha o arquivo, usando a java.io.File e java.io.FileOutputStream, para abrir e escrever em um arquivo.
Eu uso o log4j para fazer uns logs.
Sendo que quando coloquei esta Servlet para fazer alguns testes com ela recebendo 1000 requisições, mas quando chega na 970ª requisição da um erro de status 500, erro interno do servidor.
O tomcat6 não aguenta muitas requisições? Será que tenho que mudar de jsp para servlet? Alguém saberia explicar o que está acotencendo?
Quantas requisiçõe o tomcat aguenta? Será menos de 1000?
30 Respostas
Isso vai depender basicamente de três variáveis: 1) a máquina que o tomcat roda, 2) a configuração (tunning) dele, 3) e o que a sua aplicação faz, e se ela faz “performaticamente” bem.
Quanto ao número de requisições, com certeza o Tomcat suporta mais do que 1000 requisições, isso é certo.
Em todo caso, coloque aí a maneira como está sendo iniciado o tomcat.
ps.: talvez já esteja usando, mas sugiro o JMeter (jakarta.apache.org/jmeter/) para estes testes 
Bom dia,
Brother, o melhor jeito de vc obter essa informação é utilizando uma ferramenta de monitoramento.
Eu utilizo o Lambda Probe, com ele consigo ver em tempo real o número de requisições, e gráficos mostrando como está o desempenho da aplicação com aquelas X requisições.
Dá uma olhada:
http://www.lambdaprobe.org/d/index.htm
t+
Segue um bom tutorial sobre o JMeter: http://javaboutique.internet.com/tutorials/JMeter/
A máquina que o tomcat está rodando, pelo menos eu acho, muito boa, é uma 8 core, ou seja 4 processadores, cada um com 2 núcleo, e 6 a ou 8 gigas de ram, e o tomcaat tá com as configurações default.
E vou colocar aqui o código da servlet e da classe que grava os parâmetros get no arquivo.
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Properties;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import control.Catcher;
public class MainServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
File fileProperties = new File("/usr/local/apache-tomcat-6.0.16/webapps/AppWeb/WEB-INF/config/conf.properties");
FileInputStream fileInputStream = new FileInputStream(fileProperties);
Properties properties = new Properties();
properties.load(fileInputStream);
OpenFile.PATH_TXT = properties.getProperty("PATH_TXT");
OpenFile.PATH_LOG = properties.getProperty("PATH_LOG");
OpenFile.LAYOUT_LOG = properties.getProperty("LAYOUT_LOG");
OpenFile.PREFIX_FILE_LOG = properties.getProperty("PREFIX_FILE_LOG");
fileInputStream.close();
OpenFilecatcher = new OpenFile(request.getRemoteAddr(), request.getQueryString());
OpenFile.saveGetInDisk();
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<body>");
out.println("<p>REQUEST SUCESS</p>");
out.println("</body>");
out.println("</html>");
}
}
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.FileOutputStream;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import util.BrazilCalendar;
public class OpenFile{
private String query;
private String ip;
private File file;
private BrazilCalendar brazilCalendar;
private static final Logger LOGGER = Logger.getLogger(Catcher.class);
public static String PATH_TXT ;
public static String PATH_LOG ;
public static String LAYOUT_LOG = "%d{yyyy-M-dd HH:mm:ss} [%t] %p %c %x - %m%n";
public static String PREFIX_FILE_LOG ;
public OpenFile(){
super();
BasicConfigurator.configure();
PatternLayout patternLayout = new PatternLayout(Catcher.LAYOUT_LOG);
Catcher.LOGGER.setLevel(Level.INFO);
try {
this.brazilCalendar = new BrazilCalendar();
FileAppender fileAppender = new FileAppender(patternLayout, Catcher.PATH_LOG + Catcher.PREFIX_FILE_LOG + this.brazilCalendar.getFullDateForSystem("") + ".log");
OpenFile.LOGGER.addAppender(fileAppender);
OpenFile.LOGGER.info("------- NEW PROCESS -------");
OpenFile.LOGGER.debug("TIME START: " + this.brazilCalendar.getFullDateForSystemWithHour("-"));
} catch (IOException e) {
OpenFile.LOGGER.info("------- NEW PROCESS -------");
OpenFile.LOGGER.error("CANNOT OPEN FILE LOG");
OpenFileOpenFile.LOGGER.error(e.getMessage());
OpenFile.LOGGER.info("------- END PROCESS -------");
}
}
public OpenFile(String query){
this();
this.setQuery(query);
}
public OpenFile(String ip, String query){
this(query);
this.setIp(ip);
}
/**
* @return the query
*/
public String getQuery() {
return query;
}
/**
* @param query the query to set
*/
public void setQuery(String query) {
this.query = query;
OpenFile.LOGGER.info("SET QUERY: " + this.query);
}
/**
* @return the Ip
*/
public String getIp() {
return plexIp;
}
/**
* @param Ip the Ip to set
*/
public void setIp(StringIp) {
this.ip = Ip;
OpenFile.LOGGER.info("SET IP: " + this.Ip);
}
public void saveMoQueueInDisk(){
BrazilCalendar brazilCalendar = new BrazilCalendar();
String fileName = "get" + brazilCalendar.getFullDateForSystem("") + ".txt";
this.file = new File(OpenFile.PATH_TXT + fileName);
if(!this.file.exists()){
try {
this.file.createNewFile();
OpenFile.LOGGER.info("FILE CREATED");
} catch (IOException e) {
OpenFile.LOGGER.error("CANNOT CREATE FILE");
}
}
try { FileOutputStream fileOutputStream = new FileOutputStream(this.file, true);
OpenFile.LOGGER.info("FILE OPEN: " + fileOutputStream.toString());
String forFile = brazilCalendar.getFullDateForSystemWithHour("-") + " " + this.ip + " " + this.query + "\n";
fileOutputStream.write(forFile.getBytes());
fileOutputStream.flush();
fileOutputStream.close();
OpenFile.LOGGER.info("FILE CLOSED: " + fileOutputStream.toString());
Catcher.LOGGER.info("DATA SAVED");
} catch (FileNotFoundException e) {
OpenFile.LOGGER.error("MESSAGE: " + e.getMessage());
OpenFile.LOGGER.error("CAUSE: " + e.getCause());
} catch (IOException e) {
OpenFile.LOGGER.error("MESSAGE: " + e.getMessage());
OpenFile.LOGGER.error("CAUSE: " + e.getCause());
} finally{
OpenFile.LOGGER.debug("END TIME: " + this.brazilCalendar.getFullDateForSystemWithHour("-"));
OpenFile.LOGGER.info("------- END PROCESS -------");
}
}
}
Como o jeveaux disse, vai depender realmente do seu “tunning” do tomcat.
De uma olhada neste link:
http://tomcat.apache.org/tomcat-6.0-doc/config/executor.html
Abraços
Utilizar Connector NIO do tomcat 6 é interessante pois ele usa api NIO que é mais performática que a API IO normal do java.
Dá uma olhada neste artigo: http://blog.covalent.net/roller/covalent/entry/20070308
mudei de IO para buffer, mas mesmo assim continua dando erro…
como posso configurar o tomcat para um ambiente de produção?
Você pode começar a mexer no Tomcat da forma que todos fazem, aumentando a memória alocada para o Tomcat. Apesar de não ser (sempre) a melhor alternativa de tunning, em quase todos os casos onde tunning é necessário, esta configuração também se faz necessária.
No bin/catalina.sh do seu tomcat existe uma variável chamada CATALINA_OPTS. Defina esta variável usando os parâmetros a seguir:
Xms - Quantidade de memória heap inicialmente alocada
Xmx - Quantidade de memória heap máxima a ser alocada
Você pode deixar mais ou menos assim:
CATALINA_OPTS = "-Xms256M -Xmx1024M"
Vale lembrar que estes valores que eu coloquei foram “chutes”. Aconselho você fazer um teste completo com JMeter e usar um Profiler na sua aplicação para acompanhar todo o comportamento dela e chegar em valores reais para a customização do seu tomcat.
Além dos parâmetros acima existem outros que são usado com menos frequência, como Xss (que definie o tamanho inicial do stack) Xmn e Xrs (que irão definir como/quanto o heap irá aumentar e diminuir) e vários outros que você pode encontrar neste link (http://blogs.sun.com/watt/resource/jvm-options-list.html).
Você já tentou fazer esse teste sem escrever o arquivo?
Tentei agora e rodou as 1000 requisições…
o código agora está assim para salvar em disco:
FileWriter fileWriter = new FileWriter(this.file);
BufferedWriter writerFile = new BufferedWriter(fileWriter);
OpenFile.LOGGER.info("FILE OPEN: " + writerFile.toString());
String forFile = brazilCalendar.getFullDateForSystemWithHour("-") + " " + this.ip + " " + this.query + "\n";
writerFile.write(forFile);
writerFile.close();
fileWriter.close();
Eu poderia criar uma única instância de um objeto com o arquivo aberto e usar o mesmo objeto para vária requisições?
Eu iria ganhar mais desempenho?
Por acaso esse é um servidor linux?
Os sistemas Linux/Unix geralmente limitam a quantidade de arquivos abertos por processo, não sei se é o caso.
É um sistema Linux sim…
Mas acho que o erro não seja esse, pq o sistema está configurado para 760.000 file descriptor por usuário… ou não seria isso?
Só para informar, fiz um teste tirando a parte do código que grava os dados em um arquivo e o erro continua, na requisição 950 eu recebo um status 500 do tomcat…
Ué, mas você conseguiu rodar ou não conseguiu? hehehe
Cole aí o stack trace do erro que está aparecendo
O primeiro teste que eu falei que rodou foi assim, dentro da servlet tem uma classe que eu chamo que abre o arquivo, grava os dados e fecha o arquivo, então, tirei o objeto de dentro da servlet. E rodou tranquilo.
No segundo teste deixei o objeto que faz as persistências no arquivo, mas tirei a parte que abre o arquivo, grava os dados e fecha. E não rodou as 1000 requisições.
O erro que eu recebo na linha de comando é este:
HTTP request sent, awaiting response… 500 Internal Server Error
11:15:11 ERROR 500: Internal Server Error.
qual a sua server.xml?
qual o maxThreads? Qual o acceptCount?
Sobre o limite de arquivos, você pegou esse valor em “/proc/sys/fs/file-max”?
Mas acho que realmente não seja isso porque 1000 é um numero muito pequeno.
Talvez o erro seja de estouro de memoria ou algo assim.
Abra o arquivo de logs do tomcat e veja qual erro está dando e se não souber o que é, coloque aqui pra gente ver.
Com certeza isso esta com cara de ser estouro de memória e stack.
Cole aqui o stacktrace que aparece no log do tomcat.
Abraços.
No server.xml está assim:
<Connector port="8080" executor="tomcatThreadPool" protocol="HTTP/1.1"
connectionTimeout="20000" maxThreads="1000"
acceptorThreadCount="2" redirectPort="8443" socket.directBuffer="false"/>
No log do tomcat eu olhei este arquivos.
- catalina.out
Feb 19, 2008 1:29:33 PM org.apache.coyote.http11.Http11Protocol init
SEVERE: Error initializing endpoint
java.net.BindException: Address already in use:8080
at org.apache.tomcat.util.net.JIoEndpoint.init(JIoEndpoint.java:501)
at org.apache.coyote.http11.Http11Protocol.init(Http11Protocol.java:176)
at org.apache.catalina.connector.Connector.initialize(Connector.java:1058)
at org.apache.catalina.core.StandardService.initialize(StandardService.java:677)
at org.apache.catalina.core.StandardServer.initialize(StandardServer.java:795)
at org.apache.catalina.startup.Catalina.load(Catalina.java:530)
at org.apache.catalina.startup.Catalina.load(Catalina.java:550)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:260)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:412)
Feb 19, 2008 1:29:33 PM org.apache.catalina.startup.Catalina load
SEVERE: Catalina.start
LifecycleException: Protocol handler initialization failed: java.net.BindException: Address already in use:8080
at org.apache.catalina.connector.Connector.initialize(Connector.java:1060)
at org.apache.catalina.core.StandardService.initialize(StandardService.java:677)
at org.apache.catalina.core.StandardServer.initialize(StandardServer.java:795)
at org.apache.catalina.startup.Catalina.load(Catalina.java:530)
at org.apache.catalina.startup.Catalina.load(Catalina.java:550)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:260)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:412)
Feb 19, 2008 1:29:33 PM org.apache.catalina.startup.Catalina load
SEVERE: Catalina.start
LifecycleException: Protocol handler initialization failed: java.net.BindException: Address already in use:8080
at org.apache.catalina.connector.Connector.initialize(Connector.java:1060)
at org.apache.catalina.core.StandardService.initialize(StandardService.java:677)
at org.apache.catalina.core.StandardServer.initialize(StandardServer.java:795)
at org.apache.catalina.startup.Catalina.load(Catalina.java:530)
at org.apache.catalina.startup.Catalina.load(Catalina.java:550)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:260)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:412)
Feb 19, 2008 1:29:33 PM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 2560 ms
Feb 19, 2008 1:29:34 PM org.apache.catalina.core.StandardService start
INFO: Starting service Catalina
Feb 19, 2008 1:29:34 PM org.apache.catalina.core.StandardEngine start
INFO: Starting Servlet Engine: Apache Tomcat/6.0.16
Feb 19, 2008 1:29:41 PM org.apache.catalina.core.StandardContext addApplicationListener
INFO: The listener "listeners.ContextListener" is already configured for this context. The duplicate definition has been ignored.
Feb 19, 2008 1:29:41 PM org.apache.catalina.core.StandardContext addApplicationListener
INFO: The listener "listeners.SessionListener" is already configured for this context. The duplicate definition has been ignored.
Feb 19, 2008 1:29:41 PM org.apache.coyote.http11.Http11Protocol start
INFO: Starting Coyote HTTP/1.1 on http-8080
Feb 19, 2008 1:29:43 PM org.apache.jk.common.ChannelSocket init
INFO: JK: ajp13 listening on /0.0.0.0:8009
Feb 19, 2008 1:29:43 PM org.apache.jk.server.JkMain start
INFO: Jk running ID=0 time=0/303 config=null
Feb 19, 2008 1:29:43 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 15431 ms
Feb 19, 2008 1:29:44 PM org.apache.catalina.core.StandardContext addApplicationListener
INFO: The listener "listeners.ContextListener" is already configured for this context. The duplicate definition has been ignored.
Feb 19, 2008 1:29:44 PM org.apache.catalina.core.StandardContext addApplicationListener
INFO: The listener "listeners.SessionListener" is already configured for this context. The duplicate definition has been ignored.
Feb 19, 2008 1:29:44 PM org.apache.coyote.http11.Http11Protocol start
SEVERE: Error starting endpoint
java.net.BindException: Address already in use:8080
at org.apache.tomcat.util.net.JIoEndpoint.init(JIoEndpoint.java:501)
at org.apache.tomcat.util.net.JIoEndpoint.start(JIoEndpoint.java:515)
at org.apache.coyote.http11.Http11Protocol.start(Http11Protocol.java:203)
at org.apache.catalina.connector.Connector.start(Connector.java:1131)
at org.apache.catalina.core.StandardService.start(StandardService.java:531)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
at org.apache.catalina.startup.Catalina.start(Catalina.java:578)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
no localhost.2008-02-19.log:
Feb 19, 2008 1:28:29 PM org.apache.catalina.core.StandardHostValve custom
SEVERE: Exception Processing ErrorPage[exceptionType=java.lang.Exception, location=/WEB-INF/jsp/errors/servleterror.jsp]
org.apache.jasper.JasperException: File "/WEB-INF/jsp/errors/servleterror.jsp" not found
at org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:51)
at org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:409)
at org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:116)
at org.apache.jasper.compiler.JspUtil.getInputStream(JspUtil.java:847)
at org.apache.jasper.xmlparser.XMLEncodingDetector.getEncoding(XMLEncodingDetector.java:108)
at org.apache.jasper.compiler.ParserController.determineSyntaxAndEncoding(ParserController.java:309)
at org.apache.jasper.compiler.ParserController.doParse(ParserController.java:173)
at org.apache.jasper.compiler.ParserController.parse(ParserController.java:103)
at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:153)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:314)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:294)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:281)
at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:566)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:317)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:337)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:39)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:630)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:438)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:374)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302)
at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:424)
at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:271)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)
Feb 19, 2008 1:28:37 PM org.apache.catalina.core.StandardWrapperValve invoke
INFO: Servlet probe is currently unavailable
Feb 19, 2008 1:28:37 PM org.apache.catalina.core.ApplicationDispatcher invoke
WARNING: Servlet probe is currently unavailable
Feb 19, 2008 1:28:42 PM org.apache.catalina.core.StandardWrapperValve invoke
INFO: Servlet probe is currently unavailable
Feb 19, 2008 1:28:42 PM org.apache.catalina.core.ApplicationDispatcher invoke
WARNING: Servlet probe is currently unavailable
Feb 19, 2008 1:29:02 PM org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: contextDestroyed()
Feb 19, 2008 1:29:02 PM org.apache.catalina.core.ApplicationContext log
INFO: ContextListener: contextDestroyed()
Feb 19, 2008 1:29:41 PM org.apache.catalina.core.ApplicationContext log
INFO: ContextListener: contextInitialized()
Feb 19, 2008 1:29:41 PM org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: contextInitialized()
Feb 19, 2008 1:29:44 PM org.apache.catalina.core.ApplicationContext log
INFO: ContextListener: contextInitialized()
Feb 19, 2008 1:29:44 PM org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: contextInitialized()
Feb 19, 2008 1:29:45 PM org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: contextDestroyed()
Feb 19, 2008 1:29:45 PM org.apache.catalina.core.ApplicationContext log
INFO: ContextListener: contextDestroyed()
Feb 19, 2008 1:29:48 PM org.apache.catalina.core.ApplicationContext log
INFO: Loading WebApplicationContext for Spring FrameworkServlet 'probe'
(END)
O primeiro teste que eu falei que rodou foi assim, dentro da servlet tem uma classe que eu chamo que abre o arquivo, grava os dados e fecha o arquivo, então, tirei o objeto de dentro da servlet. E rodou tranquilo. No segundo teste deixei o objeto que faz as persistências no arquivo, mas tirei a parte que abre o arquivo, grava os dados e fecha. E não rodou as 1000 requisições.O erro que eu recebo na linha de comando é este:
HTTP request sent, awaiting response... 500 Internal Server Error 11:15:11 ERROR 500: Internal Server Error.
Ola só pra lembrar que se fosse um problema de falta de memoria o erro seria um OutOfMemoryError... e olha que a minha aplicação ocorria isto :((
Mas vamos lá, vc disse que com o teste que vc "exclui" a classe que persiste do servlet, isto é, vc não faz referencia nenhuma a ela, o teste funciona.. e no
teste que vc faz referencia a ela, mas dentro dela vc tira a parte que faz a persistencia, o teste dá erro...
Uma pergunta: vc está considerando que o metodo doGet, por definição é um metodo que não pode alterar o estado do servidor, tem uma palavra que define isto.. mas não lembro... então tente fazer isto pelo doPost... só pra testar ;)
Uma parada... por definição os servlets não são thread-safe, então os metodos que respondem a requisições tem que ser preparados para isto... o que pode estar acontecendo realmente seja excesso de io, olhe que vc não só abre o arquivo de output, mas um de input em toda requisição:# File fileProperties = new File("/usr/local/apache-tomcat-6.0.16/webapps/AppWeb/WEB-INF/config/conf.properties");
# FileInputStream fileInputStream = new FileInputStream(fileProperties);
# Properties properties = new Properties();
# properties.load(fileInputStream);
Uma parada... quando vc tirou a parte que faz a persistencia da classe OpenFile.... vc a comentou toda? ou só as partes de IO?
Esses logs não estão dizendo muita coisa do que estamos procurando faça o seguinte:
-Limpe o arquivo catalina.out
-Reinicie o tomcat e rode o seu teste.
Então peque o conteudo do catalina.out e cole aí pra nós.
PS.: Você não está usando connector NIO. Está usando o connector default.
Fiz mais um teste sendo que o resultado deu igual aos outros só fo aceito 972 requisições de 1000 e fiz mais requisição, depois das 1000, só que pelo browser e recebi este erro:
java.io.FileNotFoundException: $CATALINA_HOME/webapps/App/WEB-INF/config/conf.properties (Too many open files)
java.io.FileInputStream.open(Native Method)
java.io.FileInputStream.<init>(FileInputStream.java:106)
servlet.MainServlet.doGet(MainServlet.java:20)
javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
Será que uns dos motivos dos erros pode estar sendo criado pelo Log4J? Estava vendo alguns artigos na internet e vi que tem como “juntar” o Log4J com o tomcat, alguém saberia fazer essa junção?
Mudei o server.xml na parte do connector para usar o Nio.
Ficou assim:
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="20000" maxThreads="1000"
acceptorThreadCount="2" redirectPort="8443" socket.directBuffer="false"/>
E continuei tendo o mesmo erro, as 1000 requisiçõe param na 972
Fiz mais um teste sendo que o resultado deu igual aos outros só fo aceito 972 requisições de 1000 e fiz mais requisição, depois das 1000, só que pelo browser e recebi este erro:java.io.FileNotFoundException: $CATALINA_HOME/webapps/App/WEB-INF/config/conf.properties (Too many open files) java.io.FileInputStream.open(Native Method) java.io.FileInputStream.<init>(FileInputStream.java:106) servlet.MainServlet.doGet(MainServlet.java:20) javax.servlet.http.HttpServlet.service(HttpServlet.java:690) javax.servlet.http.HttpServlet.service(HttpServlet.java:803)Será que uns dos motivos dos erros pode estar sendo criado pelo Log4J? Estava vendo alguns artigos na internet e vi que tem como “juntar” o Log4J com o tomcat, alguém saberia fazer essa junção?
Pronto,
ta ai o seu problema
java.io.FileNotFoundException: $CATALINA_HOME/webapps/App/WEB-INF/config/conf.properties (Too many open files)
primeiro que um properties não pode ser aberto toda hora, ele deve ser carregado estaticamente. Eu tive uma aplicação que herdei assim que entrei na empresa, que o cara fazia isso, de tempos em tempos a aplicação estourava, justamente por causa disso.
Não há o porque carregar um arquivo de properties toda hora!!!
Para verificar o máximo de arquivos permitidos abrir no servidor, digite em seu console:
ulimit -a
Abraços
É, parece que é o problema da quantidade de arquivos abertos mesmo…
Mas como já foi dito, não abra o arquivo toda hora, não faz sentido.
É o tomcat passou de 1000 requisições, acabei fazendo todas as configurções que vcs falaram e passei a abrir o arquivo properties e o outro arquivo para guardar as requisições uma única vez, deixando os mesmos em memória.
Mas agora quando o tomcat chega a 1600 requisições ele fica lento passsando a processar praticamente uma requisição por segundo ou até mais, teria como aumentar este desempenho ainda mais?
Abaixo segue como ficou o server.xml:
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="2000" maxThreads="10000" acceptCount="5000"
acceptorThreadCount="2" redirectPort="8443" socket.directBuffer="false"/>
Verifique a memória, quanto está disponivel pra ele?
O mínimo é 256 e o máximo é 1Gb.
Amigo,
Você colocou 10 Mil Threads!
Não faça isso.
Quando se utiliza NIO basta ele não utiliza uma thread por requisição.
10000 Threads é MUITO! Deve tar mais atrapalhando do que ajudando.
Utilize o lamba probe.
Vai te ajudar a verificar o seu problema.