Bonjour,
Je me permets de vous solliciter pour un problème avec Tomcat.
Petites précisions de taille des fois que mes questions soient stupides :
- je viens de commence un nouvel emploi (2 semaines)
- ma nouvelle entreprise utilise Tomcat
- je n'ai jamais travaillé sur Tomcat auparavant
- ce sont sûrement des VMs mais je n'ai absolument pas la main sur la partie hyperviseur (les machines nous sont fournies par des partenaires)
Nous avons une application hébergée sur 3 serveurs.
2 serveurs qui n'ont jamais le soucis :
- OS : Ubuntu 18.04 LTS
- Tomcat : 8.5.39 ; source = dépôts Ubuntu
- JDK : openjdk-8 ; 8u292 ; source = dépôts Ubuntu
Le 3ème serveur - celui qui a un potentiel soucis :
- OS : Ubuntu 20.04 LTS
- Tomcat : 9.0.31 ; source = dépôts Ubuntu
- JDK : openjdk-8 ; 8u282 ; source = dépôts Ubuntu
Description du soucis : après quelques jours (2 ou 3 jours mais c'est variable) notre application devient super lente.
Exemple : si nous faisons un wget depuis le serveur sur http://127.0.0.1:8080/path/to/our/app l'application mets plusieurs secondes à répondre.
J'ai regardé plusieurs métriques comme :
- utilisation CPU
- utilisation mémoire
- utilisation réseau
- utilisation IO
- nombre d'éléments ouverts (lsof)
--> RAS : tout est au vert (la machine ne semble pas utilisée).
J'ai donc tenté de reproduire le problème dans une VM locale mais je n'y arrive pas…
Dans ma VM locale j'ai testé d'améliorer la verbosité des logs de Tomcat en modifiant le fichier /etc/tomcat9/logging.properties pour tout passer à ALL :
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional ALLrmation regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
handlers = 1catalina.org.apache.juli.AsyncFileHandler, 2localhost.org.apache.juli.AsyncFileHandler, java.util.logging.ConsoleHandler
.handlers = 1catalina.org.apache.juli.AsyncFileHandler, java.util.logging.ConsoleHandler
############################################################
# Handler specific properties.
# Describes specific configuration ALL for Handlers.
############################################################
1catalina.org.apache.juli.AsyncFileHandler.level = ALL
1catalina.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs
1catalina.org.apache.juli.AsyncFileHandler.prefix = catalina.
1catalina.org.apache.juli.AsyncFileHandler.maxDays = 90
2localhost.org.apache.juli.AsyncFileHandler.level = ALL
2localhost.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs
2localhost.org.apache.juli.AsyncFileHandler.prefix = localhost.
2localhost.org.apache.juli.AsyncFileHandler.maxDays = 90
java.util.logging.ConsoleHandler.level = ALL
java.util.logging.ConsoleHandler.formatter = org.apache.juli.SystemdFormatter
############################################################
# Facility specific properties.
# Provides extra control for each logger.
############################################################
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = ALL
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.AsyncFileHandler
# For example, set the org.apache.catalina.util.LifecycleBase logger to log
# each component that extends LifecycleBase changing state:
#org.apache.catalina.util.LifecycleBase.level = ALL
# To see debug messages in TldLocationsCache, uncomment the following line:
#org.apache.jasper.compiler.TldLocationsCache.level = ALL
# To see debug messages for HTTP/2 handling, uncomment the following line:
#org.apache.coyote.http2.level = ALL
# To see debug messages for WebSocket handling, uncomment the following line:
#org.apache.tomcat.websocket.level = ALL
Mais je n'ai pas l'impression d'attraper plus de logs quand au fonctionnement interne de Tomcat (je ne vois aucune différence entre avant et après en faites)…
Nous avons essayé de redémarrer juste notre application mais il n'y a aucun changement : le problème persiste.
La seule solution qui fonctionne c'est de redémarrer Tomcat 9.
Pour le moment j'ai des idées "à l'aveugle" qui consistent à :
- Mettre à jour le JDK pour faire le saut 8u282 --> 8u292
- Mettre à jour toute la VM + restart
- Installer un Tomcat 9 à la main pour être sur la dernière version
Mais avant j'avoue que j'aurais bien aimé avoir un peu plus de logs ou, pourquoi pas, une idée quant à la raison du problème si quelqu'un l'a déjà rencontré :)
Je vous remercie d'avance :)
# STFW ?
Posté par rycks . Évalué à 5. Dernière modification le 15 novembre 2021 à 08:31.
Hello,
je préfère dire que je n'ai aucune compétence en tomcat mais en cherchant un peu sur le web ça semble être un problème courant "tomcat 9 slow" … voir par exemple https://stackoverflow.com/questions/53640086/tomcat-9-slow-response
-> à voir si acceptorThreadCount=2 est aussi une solution dans ton cas ?
Et sinon par rapport à un problème rencontré : est-ce du https ? si oui, le serveur n'est il tout simplement pas à court de générateur de nombres pseudo aléatoires pour la pile de sécu ? ça semble idiot comme piste mais sait-on jamais … un coup d'installation de haveged pourrait donner un gros coup de pouce …
Bon courage pour la suite et sinon il doit y avoir des SSLL expertes dans ce genre de domaine qui pourraient sans doute vous apporter leur expertise.
eric.linuxfr@sud-ouest.org
[^] # Re: STFW ?
Posté par kortex . Évalué à 3.
Je vais essayer de me renseigner pour ce paramètre "acceptorThreadCount" et voir où il se mets : un grand merci ;)
Concernant le HTTPS oui s'en est mais quand on exécute une requête "locale" depuis le serveur tomcat en utilisant 127.0.0.1 alors on bypass la partie SSL et le problème est le même.
Ton idée est intéressante (et je t'en remercie) mais, et je peux me tromper, je ne pense pas que ça vienne de là :-/
[^] # Re: STFW ?
Posté par kortex . Évalué à 1.
Donc ce paramètre est en place depuis hier (15/11/2021) en début d'après-midi : wait and see :)
# Disque ?
Posté par ptit_poulet . Évalué à 2.
Le partitionnement est-il le même sur ce serveur que sur les autres ? Regarde si la SWAP n'est pas pleine ou autres quand les ralentissements commencent (déjà eu le cas pour un autre applicatif qui au bout de quelques jours devenait très très lent).
[^] # Re: Disque ?
Posté par kortex . Évalué à 1.
Le partitionnement n'est pas identique au sens strict du terme car selon les machines les partitions n'ont pas exactement la même taille.
Par contre il y a le même nombre de partition, les même points de montage, les même filesystems (pour la partie qui nous intéresse c'est du XFS).
Aucun FS n'est à 100% ni quand ça fonctionne ni quand le problème apparaît.
J'ai oublié de le dire dans mon message initial mais au niveau du swap tout est vert aussi :)
En gros, la machine ne fait rien, mais Tomcat est lent :-/
Dans ton cas c'était aussi sur du Tomcat ?
[^] # Re: Disque ?
Posté par ptit_poulet . Évalué à 1. Dernière modification le 15 novembre 2021 à 10:30.
Non pas sur Tomcat, c'était sur une box domotique Jeedom. Les actions devenaient lentes, plus possible d'afficher la partie web. Le problème venait de la SWAP.
[^] # Re: Disque ?
Posté par kortex . Évalué à 1.
Ok merci :)
# Sécu
Posté par GG (site web personnel) . Évalué à 5.
Dernièrement, il y a eu plusieurs alertes de sécurité concernant Tomcat.
Du coup, ça peut être pas mal de choses, comme un bug, ou bien des ressources détournées:
Tomcat 8 : https://security-tracker.debian.org/tracker/source-package/tomcat8
Tomcat 9 : https://security-tracker.debian.org/tracker/source-package/tomcat9
Je n'ai pas l'impression que tes Tomcat soient à jour.
Qu'est ce que tu utilises comme gestionnaire de paquet?
Qu'est ce que tu utilises pour déterminer la consommation des ressources CPU, disques, réseaux?
Pourquoi bloquer la publicité et les traqueurs : https://greboca.com/Pourquoi-bloquer-la-publicite-et-les-traqueurs.html
[^] # Re: Sécu
Posté par kortex . Évalué à 2.
J'utilise apt / apt-get (ce sont des serveurs Ubuntu).
Et malheureusement je suis sur la dernière version que donne Ubuntu : 9.0.31 (c'est pour ça que je garde en tête de taper une installation manuelle)
J'utilise des outils relativement classiques comme :
[^] # Re: Sécu
Posté par GG (site web personnel) . Évalué à 2.
Sur Debian, pour Tomcat9 on a la version 9.0.43-2~deb11u3
et pour Tomcat8, ça doit être en old-stable, pas disponible en stable.
Pourquoi bloquer la publicité et les traqueurs : https://greboca.com/Pourquoi-bloquer-la-publicite-et-les-traqueurs.html
[^] # Re: Sécu
Posté par kortex . Évalué à 1.
C'est étrange que Debian fournisse une version plus récente mais pourquoi pas :-)
Pour Ubuntu si je dois mettre à jour je ne vais pas avoir le choix que de passer par une installation manuelle (ou de chercher des paquets ailleurs).
[^] # Re: Sécu
Posté par NeoX . Évalué à 3.
tout simplement parce que :
CQFD
[^] # Re: Sécu
Posté par kortex . Évalué à 1.
Je suis fatigué je n'avais même pas pensé à ça :D
# Le problème vient de se produire
Posté par kortex . Évalué à 3.
Le problème vient tout juste de se reproduire.
J'ai donc :
Reste à attendre et espérer :)
# service de virtualisation
Posté par Marc Quinton . Évalué à 4.
il est possible que le service d'infrastructure qui héberge tes VM ait des soucis et que tu ne soit pas en mesure de les identifier.
Pour ma part, je co-exploite une PF Proxmox, et suivant la conf des noeuds de virtualisation (swappiness) certaines VM peuvent être forcées de swapper sur le serveur sans que tu ai le moyen de le savoir coté VM.
si tu peux installer un peu de monitoring et faire des mesures :
- ping localhost
- latence CPU (je ne sais pas bien comment) ; peut-etre dans une boucle : sleep 1s ; et lire l'heure et voir s'il y a un décalage entre ce que devrait être l'heure et ce qui est lu ; ne pas hésiter a placer le process en priorité basse
- ping sur la route par défaut
grapher le tout sur un dashboard type influxdb + chronograf ou ce qui t'arranges le mieux ; tu pourras avoir des billes pour de la négo auprès des admins.
[^] # Re: service de virtualisation
Posté par NeoX . Évalué à 6.
toutafais,
j'ai eu le cas (et j'ai encore la cas), de machines physiques qui font beaucoup d'IO disque, mais qui ne montrent rien dans les VMs qui pourtant pédalent comme pas possible, jusqu'à perdre des pings
donc je dirais que si tu ne vois rien sur les VMs, c'est peut-etre que le probleme vient d'ailleurs.
à voir si tu peux déplacer la VM ubuntu 20.04 vers un autre serveur physique par exemple.
de meme il faudrait voir si les VM ont la meme quantité de RAM, de swap, la meme techno de disques physiques derriere…
et si ca se trouve ton code sous tomcat8 (ubuntu 18) a des bugs sans effet, alors que sur la VM en ubuntu 20.04, avec le tomcat9, ces memes bugs sont 'pris' en compte
le ralentissement sans visibilité me ferait penser à une fuite memoire, mais si tu dis que le top ne dit rien :/
[^] # Re: service de virtualisation
Posté par kortex . Évalué à 2. Dernière modification le 15 novembre 2021 à 17:45.
Je vous fais une réponse commune à tous les deux :)
Déjà merci pour les suggestions / les pistes.
Je vais effectivement voir si je peux mettre en place rapidement quelque chose car il peut effectivement y avoir des choses intéressantes.
Concernant les fournisseurs, malheureusement ce ne sont pas des fournisseurs publics comme OVH, etc.
Donc quand je dis que je n'ai accès à rien je n'ai accès à rien :-D : je ne sais même pas quelle technologie de virtualisation est derrière + quand je récupère les VMs l'OS est déjà installé / pré-configuré.
De plus, de part notre activité, nous avons plusieurs fournisseurs ce qui signifie que les machines sont peut-être sur des hyperviseurs différents, que les machines ont peut-être des configurations de bases différentes, etc. Bref, c'est pas simple…
Est-ce que je peux déplacer ma VM ? Clairement pas sauf à potentiellement faire une demande (en espérant que ce soit bien des VM et qu'il y ait une technologie type vMotion sur l'hyperviseur du fournisseur :-D) : je peux toujours poser la question demain :)
J'y pensais à ça mais il n'y a vraiment RIEN qui apparaît dans les logs c'est vraiment bizarre…
C'est juste que d'un coup on voit que ça mets une plombe à répondre…
Pour la fuite mémoire j'y ai pensé mais effectivement je maintiens : il n'y a aucun signe :-/
Le cycle est d'environ 2-3 jours : vendredi nous avons redémarré le tomcat vers 17H30 et de nouveau aujourd'hui vers 13H30 par exemple…
[^] # Re: service de virtualisation
Posté par Marc Quinton . Évalué à 2. Dernière modification le 15 novembre 2021 à 18:08.
Concernant les devices visibles sur Linux, parfois, on peut voir quand ils sont spécifiques à un hyperviseur donné. A voir si on saurait le détecter.
Sinon, comme dans bcp d'entreprises, tu bénéficies de VM dans un mode contraint plutôt qu'en self-service ; c'est un lieu commun. Pour ce qui nous concerne, j'ai essayé d'avoir le plus de transparence possible en documentant nos services sur un Wiki accessibles à tous (ou presque).
[^] # Re: service de virtualisation
Posté par NeoX . Évalué à 3.
les premiers champs de lshw ou dmidecode permettre parfois de voir cela
j'ai des machines qui affiche alors clairement que le Vendor est Vmware par exemple
sinon, pour vmware y a regarder si les vmtools sont en train de tourner
ps fax | grep vmtoolsd
pour qemu/kvm parfois le qemu-guest-agent
ps fax | grep agent
[^] # Re: service de virtualisation
Posté par Marc Quinton . Évalué à 2. Dernière modification le 16 novembre 2021 à 10:02.
un autre lien sur le sujet:
- https://qastack.fr/unix/89714/easy-way-to-determine-virtualization-technology
[^] # Re: service de virtualisation
Posté par Marc Quinton . Évalué à 2. Dernière modification le 16 novembre 2021 à 10:03.
merci pour les infos ; voici ce que j'obtiens avec cette commande sur une VM proxmox / KVM :
par ailleurs, nous avons l'habitude d'installer un client guest-agent qui permet d'entrer en communication avec l'hyperviseur. Je ne sais pa s'il y a un lien avec le module ci-dessous.
on voit aussi qq infos avec dmidecode:
il semble plus d'avoir des infos avec une pseudo VM qui est basé sur LXC ; je peux le cas échéant donner des pistes.
[^] # Re: service de virtualisation
Posté par Marc Quinton . Évalué à 2. Dernière modification le 15 novembre 2021 à 22:15.
encore une:
encore plusieurs méthodes ici : https://ostechnix.com/check-linux-system-physical-virtual-machine/
[^] # Re: service de virtualisation
Posté par Marc Quinton . Évalué à 4.
pour la latence CPU, tu peux regarder ce script : https://github.com/tanelpoder/0xtools/blob/master/bin/schedlat
- le paramètre passé est le PID du process à surveiller (process java dans ce cas).
[^] # Re: service de virtualisation
Posté par kortex . Évalué à 2.
Alors je vais faire une réponse complète à tout le monde sur ce fil :)
Je viens de mettre en place un script qui prends quelques mesures toutes les 60 secondes :
- w
- top
- free
- ping d'une ip publique bien connue pour être un serveur DNS d'un célèbre moteur de recherche
- ping de la gateway
- wget de l'application sur son adresse externe
- wget de l'application sur 127.0.0.1:8080 pour bypasser le load balancer nginx en frontal
- iotop
J'espère capturer quelque chose pendant le problème…
Concernant la détection du type d'hyperviseur je reçois un "vm-other" et je n'ai aucun agent qui tourne : je vais essayer de me renseigner.
Concernant le script schedlat: je l'ai testé localement, il m'a l'air intéressant (merci beaucoup), mais je voudrais le ralentir un peu car il va me produire un peu beaucoup de logs :D Du coup je l'ai pas encore mis sur la machine qui a le problème.
# limite mémoire de la JVM
Posté par wismerhill . Évalué à 8.
Une application java qui devient lente après quelques jours, ça me fait penser à un problème de fuite de mémoire. Quand la JVM s'approche de sa limite de mémoire allouée, le garbage collector doit de plus en plus travailler pour essayer de récupérer de la mémoire pour pouvoir créer de nouveaux objets.
Donc vérifie si la consommation mémoire de tomcat n'aurait pas tendance à augmenter avec le temps.
Si c'est normal pour votre application de consommer beaucoup de mémoire, vérifie si la limite de la JVM est réglée suffisamment haut pour votre cas d'utilisation.
[^] # Re: limite mémoire de la JVM
Posté par BAud (site web personnel) . Évalué à 3.
sans doute pas les meilleurs tutos mais ça peut donner des pistes pour diagnostiquer :
https://linuxtut.com/fr/878000dbe3b5af0e95c2/
https://docs.oracle.com/cd/E49461_01/doc.70/e52859/cnf_jvmgc.htm#CASCG819
[^] # Re: limite mémoire de la JVM
Posté par paulez (site web personnel) . Évalué à 3.
En effet c'est un problème courant avec la JVM, surtout qu'on peut la configurer pour limiter la mémoire allouée pour le tas (la "heap" en langue de Shakespeare). C'est pour ça que ça peut rester invisible dans les métriques système.
Tu peux tester en augmentant cette limite avec le paramètre -Xmx.Tu peux aussi surveiller en temps réel le temps passé à utiliser le ramasse-miette (Garbage Collector) avec JMX et les métriques CollectionTime et CollectionCount.
[^] # Re: limite mémoire de la JVM
Posté par kortex . Évalué à 1.
Je vais regarder / lire tout ça au plus vite : merci :)
[^] # Re: limite mémoire de la JVM
Posté par benja . Évalué à 1.
Dans ce cas cela se verrait au niveau de la charge cpu.
[^] # Re: limite mémoire de la JVM
Posté par wismerhill . Évalué à 4.
C'est pas faux.
Mais dans ce cas le problème pourrait être inverse:
Si la limite mémoire de la JVM est trop élevée par rapport à la quantité de RAM effectivement disponible, le garbage collector ne va pas essayer de libérer de la mémoire tant qu'il a de la marge sur la limite imposée (ce comportement est configurable). Mais quand trop peu de RAM est disponible, le système va commencer à déplacer des pages mémoire en swap.
À partir de là, si une requête à besoin d'utiliser des données qui sont parties en swap, il devra attendre qu'elles soient re-déplacées en RAM, et d'autres seront déplacées en swap pour faire de la place (d'où cercle vicieux).
L'impact sur les statistiques d'IO n'est pas forcément énorme, puisque c'est seulement quand on en a besoin qu'il faut lire la swap.
Si c'est ça le problème, alors régler la limite mémoire de la jvm plus basse améliorera les performances en forçant le garbage collector à libérer de la mémoire plus souvent.
# Commentaire supprimé
Posté par tyleraustin . Évalué à -9. Dernière modification le 17 novembre 2021 à 18:18.
Ce commentaire a été supprimé par l’équipe de modération.
# on sait jamais, le grand classique
Posté par benja . Évalué à 3.
Regardes toujours du côté du traffic dns, au cas où ton tomcat/app ferait des résolutions inverses. Peut-être un truc qui a changé au niveau de la glibc, ou cette crasse de systemd-resolvd qui a décidé de changer de dns parcequ'il y a eu un drop UDP (quelle crasse ce truc, je me répète)… 'fin au doigt mouillé, je dirais ça, un timeout réseau quelque part, voir un rate limiting à l'extérieur… La version de la JVM a aussi peut-être changé quant à la gestion du cache DNS ou à la préférence IPv4/IPv6. Un tcpdump sur autre chose que ton port 8080 pourra peut-être t'éclairer…
[^] # Re: on sait jamais, le grand classique
Posté par kortex . Évalué à 1. Dernière modification le 29 novembre 2021 à 08:31.
Désolé j'ai complètement raté ton message… : merci pour les suggestions que je garde précieusement de côté.
Alors à ma connaissance il n'y a aucune résolution DNS inverse : que de la résolution DNS directe ou des adresses IP directes.
Ce qui est étrange c'est que le problème est apparu du jour au lendemain sur un serveur qui a été mis en production il y a un presque un an (je me fie à ce que l'on me dit vu que moi je suis arrivé il y a un mois :-D)
Pour l'instant je touche du bois : depuis que j'ai mis à jour la JDK vers la dernière mise à jour mineure + ajouté le paramètre acceptorThreadCount="2" dans server.xml le soucis n'est pas réapparu (d'où le fait que j'ai été silencieux dans ce post : j'attendais de voir) :-)
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.