Bonjour,
Depuis plusieurs mois, je me penche régulièrement sur un problème tomcat d’accumulation de thread qui bloque les traitements serveurs jusqu'à ce que le nombre maximum de thread soit finalement atteint que le tomcat soit coupé.
Contexte :
Il s'agit un projet professionnel où l'application est utilisée par une soixantaine d'opérateurs.
Comme tout client lourd, l'application se connecte à un serveur d'application (ici, tomcat) pour effectuer ses requêtes en base de données. Pour cela, il va soit créer un nouveau thread serveur, soit en utiliser un ouvert et disponible.
Le problème survient de manière totalement aléatoire. Il arrive qu'un des traitements se bloque pour une raison X et tous les traitements suivant (donc les nouveaux threads ou les ré-utilisé) ne mettent en mode "wait" et s'accumulent constamment.
Voici une capture d'écran du manager à cet instant :
La première piste, ou pour dire vrai, la seule, qu'on a eu était vis à vis de la base de données. Certaines requêtes pouvaient être longue. On a donc augmenté le nombre maximum de thread actifs, ce qui a été bénéfique pendant plusieurs mois (cf. plus bas, le appContext.xml)
Cette modification a eu pour effet de tuer le thread après une période de X seconde libérant alors les thread suivant, ce qui a empêché de faire tomber le tomcat, mais bloquant les opérateurs le temps de la durée de vie du thread bloquant...
Configuration
Au niveau tomcat, le serveur.xml (cf. pièce jointe)
Au niveau webApp, appContext.xml (cf. pièce jointe)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 <Service name="Catalina"> <Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="200" minSpareThreads="40"/> <Connector executor="tomcatThreadPool" port="8081" protocol="org.apache.coyote.http11.Http11NioProtocol" scheme="http" connectionTimeout="40000" maxHttpHeaderSize="8192" acceptorThreadCount="4" redirectPort="8443" xpoweredBy="false" server="server" allowTrace="false" /> ...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" /> <property name="url" value="jdbc:oracle:thin:@${host}:${port}:${database}" /> <property name="username" value="${database.username}" /> <property name="password" value="${database.password}" /> <!--property name="testOnBorrow" value="true" /> <property name="testWhileIdle" value="true" /> <property name="validationQuery" value="select 1 from dual" /--> <property name="maxWait" value="10000" /> <property name="maxIdle" value="70" /> <property name="maxActive" value="-1" /> </bean>
L'objectif
Au pire, limiter le durée de vie d'un thread tomcat. De façon nominale, les traitements serveurs ne dépassent jamais les 30 secondes. On a essayé d'utiliser de nombreux paramètres, en vain...
Si quelqu'un a la moindre idée, je suis preneur.
Merci
Partager