web-dev-qa-db-fra.com

Tomcat consomme beaucoup de CPU

Tomcat.exe consomme 75% du CPU. Quelqu'un sait-il pourquoi cela se produit et comment peut-on le réduire?

J'utilise Tomcat5.5 et J2SDK v 1.4.2_12

12
Miral

Pour comprendre ce qui se passe, vous devriez essayer de l'exécuter sous un profileur. Essayez le YourKit ( http://www.yourkit.com/ ) ou Netbeans ( http://profiler.netbeans.org/docs/help/5.5/profile_j2ee_profileproject.html ).

Les YourKit ont une meilleure intégration avec Tomcat.

4
J-16 SDiZ

Si vous utilisez 75% du processeur et que vous ne comprenez pas pourquoi, je vous suggère d'envoyer un kill -3 au processus Tomcat (ctrl-break si vous avez une console) pour obtenir un vidage de thread (lorsque la charge est élevée!). D'après mon expérience, la plupart des discussions devraient être soit inactives, soit en io-wait. Recherchez toute branche de code qui a des occurrences répétées dans les traces de la pile et qui est probablement votre coupable (non-io attend!). C'est le "profileur du pauvre" qui est souvent le meilleur moyen et le plus efficace pour résoudre ces problèmes.

10
krosenvold

Lambda Probe est un outil très pratique pour surveiller Tomcat.

Utilisez-vous un système à quatre processeurs? Tomcat fonctionne probablement à 100% dans 3 d’entre eux. Je voudrais d'abord tester une boucle infinie ou quelque chose comme ça dans une application.

4
kgiannakakis

Mes journaux étaient pleins de journaux Tomcat. Je les ai tous supprimés et l'utilisation du processeur a considérablement diminué.

4
Murali

Tout d’abord (cela s’applique à toutes les applications Java), vous devez déterminer quel thread utilise le processeur. Ceci est possible dans JDK 1.6. Pour ce faire, utilisez Java.lang.management.ManagementFactory.getThreadMXBean (). Voici un exemple d'utilisation (JSP):

<%@ page import="Java.lang.management.*, Java.util.*" %>
<%!
    Map cpuTimes = new HashMap();
    Map cpuTimeFetch = new HashMap();
%><%
long cpus = Runtime.getRuntime().availableProcessors();
ThreadMXBean threads = ManagementFactory.getThreadMXBean();
long now = System.currentTimeMillis();
ThreadInfo[] t = threads.dumpAllThreads(false, false);
for (int i = 0; i < t.length; i++) {
    long id = t[i].getThreadId();
    Long idid = new Long(id);
    long current = 0;
    if (cpuTimes.get(idid) != null) {
        long prev = ((Long) cpuTimes.get(idid)).longValue();
        current = threads.getThreadCpuTime(t[i].getThreadId());
        long catchTime = ((Long) cpuTimeFetch.get(idid)).longValue();
        double percent = (current - prev) / ((now - catchTime) * cpus * 10000);
        if (percent > 0 && prev > 0) {
            out.println("<li>" + t[i].getThreadName() + " " + percent + " (" + prev + ", " + current + ")");    
        }
    }
    cpuTimes.put(idid, new Long(current));  
    cpuTimeFetch.put(idid, new Long(now));
}
%>

Après cela, vous pouvez obtenir un dump de thread et analyser le code de ce thread pour corriger une utilisation excessive du processeur.

3
huksley

Toutes les réponses traitent de la manière d'effectuer un diagnostic exact. De plus, j'ajouterais que, d'après mon expérience, une boucle infinie dans l'une de vos applications est probablement la cause.

Comme l'a dit J-16 SDiZ, le mieux est de lancer le profileur pour limiter le problème à une seule application.

1
James McMahon

Nous venons de résoudre un problème concernant notre instance Tomcat fonctionnant avec une utilisation très élevée du processeur, balançant jusqu'à 100% et plus toutes les quelques secondes, puis brièvement à nouveau. Cela s'est produit toute la journée et toute la nuit, que le serveur effectue un travail ou non. Nous utilisons Tomcat 8 avec Java 8. 

Nous n'avons pas trouvé notre solution dans une recherche sur le Web, je la poste donc ici dans l'espoir d'aider quelqu'un d'autre.

Nous avions utilisé l'option de configuration du répertoire Tomcat/conf/Catalina/localhost, dans laquelle nous avons dirigé Tomcat vers un autre répertoire, autre que son propre répertoire webapps. Les fichiers XML de ce répertoire ressemblent à ceci:

<?xml version='1.0'?>
<Context
docBase="/opt/dspace/amaddev/dspace-6.3/webapps/jspui"
reloadable="true"
cachingAllowed="false"/>

Et cela a fonctionné, Tomcat a exécuté le code dans ces répertoires plutôt que dans son propre répertoire webapps. Cependant, nous avons eu ce problème avec l'augmentation continue de l'utilisation du processeur.

Pour tester, nous avons supprimé les fichiers XML du répertoire conf/Catalina/localhost et redémarré Tomcat. Soudain, nous avons retrouvé un Tomcat normal et bien élevé. Afin de diriger le Tomcat vers cet autre répertoire (où nous compilons notre code dspace), nous avons simplement utilisé l'entrée Host dans conf/server.xml et modifié le paramètre appBase dans notre répertoire dspace:

<Host name="localhost"  appBase="/opt/dspace/amaddev/dspace-6.3/webapps"
        unpackWARs="true" autoDeploy="true">

Ceci accomplit maintenant ce que nous voulions avec une très faible utilisation de l'unité centrale (inférieure à 1%) lorsque le serveur est silencieux.

0
excyberlabber

Cela est probablement dû aux applications que vous exécutez sur Tomcat. Bien sûr, si le trafic de vos applications est très important, cela pourrait aussi en être la raison.

0
Juha Syrjälä

Dans mon cas, je venais d'installer Tomcat8 avec les paramètres par défaut. Je devais définir les paramètres de la mémoire -Xms -Xmx. Une fois, j’ai augmenté l’allocation de mémoire vers la machine virtuelle Java, l’utilisation du processeur a considérablement diminué. 

0
Bhushan Patil