{"id":1258,"date":"2021-04-12T12:29:47","date_gmt":"2021-04-12T10:29:47","guid":{"rendered":"https:\/\/www.loicmathieu.fr\/wordpress\/?p=1258"},"modified":"2021-04-28T12:25:23","modified_gmt":"2021-04-28T10:25:23","slug":"profiler-une-application-java-dans-un-conteneur-deploye-dans-kubernetes-avec-jfr-java-flight-recorder","status":"publish","type":"post","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/profiler-une-application-java-dans-un-conteneur-deploye-dans-kubernetes-avec-jfr-java-flight-recorder\/","title":{"rendered":"Profiler une application Java dans un conteneur d\u00e9ploy\u00e9 dans kubernetes avec JFR &#8211; Java Flight Recorder"},"content":{"rendered":"<p>La plupart des clients chez lesquels j&rsquo;interviens aujourd&rsquo;hui utilisent Kubernetes pour d\u00e9ployer leurs applications.<\/p>\n<p>Bien que Kubernetes soit un super outil, si on a besoin de ce type d&rsquo;outil (qui est une discussion dans laquelle je ne rentrerais pas ici), il peut apporter une certaine complexit\u00e9 quant aux moyens de \u00ab\u00a0regarder\u00a0\u00bb le comportement de nos applications en cours de fonctionnement.<\/p>\n<p>Quand j&rsquo;ai un probl\u00e8me de performance sur une application, j&rsquo;utilise r\u00e9guli\u00e8rement un profiler Java. Il en existe de nombreux, mais tous n\u00e9cessitent de pouvoir se connecter \u00e0 l&rsquo;application d&rsquo;une certaine mani\u00e8re (port distant ou local, agent Java, &#8230;).<\/p>\n<p>Prenons comme exemple une application traitant des messages Kafka et utilisant une image de base openjdk-15. Cette application n&rsquo;ayant pas besoin d&rsquo;acc\u00e8s distant, elle n&rsquo;exposera aucun port via Kubernetes. La seule mani\u00e8re de s&rsquo;y connecter sera donc en se connectant au conteneur.<\/p>\n<p>Voici une commande pour ouvrir un shell sur un Pod avec un seul conteneur (si plusieurs conteneurs, il faut ajouter le nom du conteneur sur lequel vous voulez vous connecter) :<\/p>\n<pre>kubectl exec -ti name-of-my-pod -- sh\n<\/pre>\n<p>Une fois connect\u00e9 dans le conteneur, quelques constatations :<\/p>\n<ul><li>L&rsquo;image openjdk ne me permet pas de lister les process via ps ni jps.<\/li>\n\n<li>L&rsquo;image openjdk ne contient ni curl ni wget pour t\u00e9l\u00e9charger un outil quelconque.<\/li>\n\n<li>Mon conteneur ne peut pas installer de nouveaux packages : pour des raisons de s\u00e9curit\u00e9 \u00e9vidente, il tourne avec un utilisateur avec des droits limit\u00e9s.<\/li>\n<\/ul>\n<p>Donc, ce n&rsquo;est pas possible de t\u00e9l\u00e9charger AsynchProfiler, par exemple, pour profiler mon application.<\/p>\n<p>Ne pouvant m\u00eame pas lister les process, je ne peux pas utiliser un des outils fournis par la JVM non plus.\nMais attendez ! En fait, pas besoin de lister les process !\nDans un conteneur, il n&rsquo;y a g\u00e9n\u00e9ralement qu&rsquo;un process, je peux donc acc\u00e9der au process de ma JVM via le pid 1 ! (Ce n&rsquo;est pas toujours vrai, si votre conteneur a red\u00e9marr\u00e9, s&rsquo;il y a plusieurs conteneurs sur votre pod ou des conteneurs d&rsquo;init, il se peut que le pid soit plus \u00e9lev\u00e9, mais il est facilement trouvable en testant 2, 3, 4, &#8230;).<\/p>\n<p>Vous pourrez donc utiliser jinfo, par exemple, pour r\u00e9cup\u00e9rer les informations sur votre JVM : <code>jinfo 1<\/code><\/p>\n<p>M\u00eame si vous ne pouvez rien installer dans votre conteneur ni t\u00e9l\u00e9charger d&rsquo;outils, vous pouvez toujours utiliser ce que vous fournit la JVM, et c&rsquo;est l\u00e0 qu&rsquo;entre en jeux JFR &#8211; Java Flight Recorder.<\/p>\n<p>JFR est un outil int\u00e9gr\u00e9 \u00e0 la JVM qui permet de monitorer une JVM avec un impact minimal sur les performances de celle-ci. Il monitore une JVM via un ensemble d&rsquo;\u00e9v\u00e9nements qui sont enregistr\u00e9s pour \u00eatre ensuite analys\u00e9s via JMC &#8211; Java Mission Control.<\/p>\n<p>JFR peut \u00eatre lanc\u00e9 de deux mani\u00e8res : via la ligne de commande de la JVM, ou via jcmd. Comme nous ne voulons pas modifier la ligne de commande de la JVM, surtout que cela n\u00e9cessiterait un red\u00e9marrage de celle-ci, on va utiliser jcmd pour d\u00e9marrer un enregistrement.<\/p>\n<pre>jcmd 1 JFR.start settings=profile\n<\/pre>\n<p>Ici on utilise l&rsquo;option <code>settings=profile<\/code> pour d\u00e9marrer JFR en mode profiling, ce qui active plus d\u2019\u00e9v\u00e9nements que le mode par d\u00e9faut. Il est possible de sp\u00e9cifier un fichier XML de settings qui contient la liste exacte des \u00e9v\u00e9nements JFR \u00e0 activer pour plus de flexibilit\u00e9.<\/p>\n<p>La sortie de la commande est la suivante :<\/p>\n<pre>Started recording 1. No limit specified, using maxsize=250MB as default.\n\nUse jcmd 1 JFR.dump name=1 filename=FILEPATH to copy recording data to file.\n<\/pre>\n<p>Elle nous indique comment arr\u00eater la session d&rsquo;enregistrement.<\/p>\n<p>Au bout de quelques temps, vous pouvez arr\u00eater la session via :<\/p>\n<pre> \njcmd 1 JFR.dump name=1 filename=\/tmp\/profile.jfr\n<\/pre>\n<p>Ensuite, pour pouvoir exploiter votre session JFR dans JMC, vous devez sortir du conteneur puis r\u00e9cup\u00e9rer le fichier de profil sur votre poste local. Ceci se fait via la commande kubectl :<\/p>\n<pre>kubectl cp name-of-my-pod:\/tmp\/profile.jfr profile.jfr\n<\/pre>\n<p>En utilisant les outils \u00e0 disposition dans toute installation de Kubernetes et de la JVM, on peut facilement d\u00e9clencher une session d&rsquo;enregistrement JFR sur une application en cours d&rsquo;ex\u00e9cution, r\u00e9cup\u00e9rer celle-ci localement puis l&rsquo;analyser. Cela nous permet de monitorer une application en cours d&rsquo;ex\u00e9cution dans un conteneur d\u00e9ploy\u00e9 dans Kubernetes sans installation d&rsquo;outils suppl\u00e9mentaires et donc sans mettre en danger la s\u00e9curit\u00e9 de nos conteneurs.<\/p>","protected":false},"excerpt":{"rendered":"<p>La plupart des clients chez lesquels j&rsquo;interviens aujourd&rsquo;hui utilisent Kubernetes pour d\u00e9ployer leurs applications. Bien que Kubernetes soit un super outil, si on a besoin de ce type d&rsquo;outil (qui est une discussion dans laquelle je ne rentrerais pas ici), il peut apporter une certaine complexit\u00e9 quant aux moyens de \u00ab\u00a0regarder\u00a0\u00bb le comportement de nos applications en cours de fonctionnement. Quand j&rsquo;ai un probl\u00e8me de performance sur une application, j&rsquo;utilise r\u00e9guli\u00e8rement un profiler Java. Il en existe de nombreux, mais&#8230;<p class=\"read-more\"><a class=\"btn btn-default\" href=\"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/profiler-une-application-java-dans-un-conteneur-deploye-dans-kubernetes-avec-jfr-java-flight-recorder\/\">Lire la suite<span class=\"screen-reader-text\"> Lire la suite<\/span><\/a><\/p><\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":4,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[9],"tags":[11,192,169,159],"class_list":["post-1258","post","type-post","status-publish","format-standard","hentry","category-informatique","tag-java","tag-jfr","tag-monitoring","tag-performance"],"aioseo_notices":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":1459,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/profiler-un-pod-dans-kubernetes-avec-kubectl-flame\/","url_meta":{"origin":1258,"position":0},"title":"Profiler un pod dans Kubernetes avec kubectl flame","author":"admin","date":"mercredi  4 mai 2022","format":false,"excerpt":"Kubectl flame est un plugin pour kubectl qui vous permet de profiler des applications en production avec un faible co\u00fbt en g\u00e9n\u00e9rant des FlameGraphs. C'est un projet Yahoo. Il s'installe via krew, le gestionnaire de plugin pour kubectl, et permet de g\u00e9n\u00e9rer des FlameGraphs pour des applications en Go, Java\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/cpu-mysql-updated.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/cpu-mysql-updated.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/cpu-mysql-updated.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/cpu-mysql-updated.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":1946,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/java-25-quoi-de-neuf\/","url_meta":{"origin":1258,"position":1},"title":"Java 25 : Quoi de neuf?","author":"admin","date":"vendredi  4 juillet 2025","format":false,"excerpt":"Maintenant que Java 25 est features complete (Rampdown Phase One au jour d\u2019\u00e9criture de l\u2019article), c\u2019est le moment de faire le tour des fonctionnalit\u00e9s qu\u2019apporte cette nouvelle version, \u00e0 nous, les d\u00e9veloppeurs. Cet article fait partie d\u2019une suite d\u2019article sur les nouveaut\u00e9s des derni\u00e8res versions de Java, pour ceux qui\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1877,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/java-24-quoi-de-neuf\/","url_meta":{"origin":1258,"position":2},"title":"Java 24 : quoi de neuf ?","author":"admin","date":"vendredi 10 janvier 2025","format":false,"excerpt":"Maintenant que Java 24 est features complete (Rampdown Phase One au jour d\u2019\u00e9criture de l\u2019article), c\u2019est le moment de faire le tour des fonctionnalit\u00e9s qu\u2019apporte cette nouvelle version, \u00e0 nous, les d\u00e9veloppeurs. Cet article fait partie d\u2019une suite d\u2019article sur les nouveaut\u00e9s des derni\u00e8res versions de Java, pour ceux qui\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1758,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/java-22-quoi-de-neuf\/","url_meta":{"origin":1258,"position":3},"title":"Java 22 : quoi de neuf ?","author":"admin","date":"lundi  8 janvier 2024","format":false,"excerpt":"Maintenant que Java 22 est features complete (Rampdown Phase One au jour d\u2019\u00e9criture de l\u2019article), c\u2019est le moment de faire le tour des fonctionnalit\u00e9s qu\u2019apporte cette nouvelle version, \u00e0 nous, les d\u00e9veloppeurs. Cet article fait partie d\u2019une suite d\u2019article sur les nouveaut\u00e9s des derni\u00e8res versions de Java, pour ceux qui\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1090,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/quarkus-jlink-et-application-class-data-sharing-appcds\/","url_meta":{"origin":1258,"position":4},"title":"Quarkus, jlink et Application Class Data Sharing (AppCDS)","author":"admin","date":"vendredi 29 mai 2020","format":false,"excerpt":"Quarkus est optimis\u00e9 pour d\u00e9marrer rapidement et avoir une empreinte m\u00e9moire tr\u00e8s faible. Ceci est vrai en d\u00e9ployant dans une JVM standard mais encore plus en d\u00e9ployant notre application comme un ex\u00e9cutable natif via GraalVM. Quarkus facilite grandement la cr\u00e9ation d\u2019ex\u00e9cutable natif, gr\u00e2ce \u00e0 \u00e7a, une application Quarkus d\u00e9marre en\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/quarkus_metrics_graphic_bootmem_wide-1024x473.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/quarkus_metrics_graphic_bootmem_wide-1024x473.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/quarkus_metrics_graphic_bootmem_wide-1024x473.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":1153,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/profiler-une-image-native-graalvm-avec-perf\/","url_meta":{"origin":1258,"position":5},"title":"Profiler une image native GraalVM avec perf","author":"admin","date":"lundi 16 novembre 2020","format":false,"excerpt":"L'outil GraalVM native-image permet de g\u00e9n\u00e9rer un ex\u00e9cutable natif (ou image native) depuis votre application Java. Cet ex\u00e9cutable natif va d\u00e9marrer tr\u00e8s rapidement et avoir une empreinte m\u00e9moire beaucoup plus faible qu'une application Java traditionnelle; au prix de performances en pic r\u00e9duites et d'un temps de cr\u00e9ation de ce package\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/flamegraph-2.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/flamegraph-2.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/flamegraph-2.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/flamegraph-2.png?resize=700%2C400&ssl=1 2x"},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/posts\/1258","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/comments?post=1258"}],"version-history":[{"count":0,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/posts\/1258\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/media?parent=1258"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/categories?post=1258"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/tags?post=1258"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}