Java-buildpack: Impossible d'exécuter des applications Spring Boot avec la configuration par défaut et <512M

Créé le 31 déc. 2018  ·  8Commentaires  ·  Source: cloudfoundry/java-buildpack

Le fait qu'il ne soit pas possible d'exécuter un Spring Boot hello world (MVC ou WebFlux) avec moins de 512M et que la plupart des applications non triviales nécessitent au moins 1G sur Cloud Foundry est assez frustrant pour les utilisateurs, et donne la fausse impression que Spring Le démarrage ne peut pas fonctionner avec moins de 1 Go de mémoire.

Nous travaillons avec @dsyer , l'équipe Boot et d'autres pour optimiser Spring Framework et Spring Boot afin de générer moins de pression GC et de réduire la consommation de mémoire, mais j'ai tendance à penser que nous pourrions également améliorer Cloud Foundry pour mieux gérer cela.

J'ai soulevé https://github.com/cloudfoundry/java-buildpack-memory-calculator/issues/24 à propos de la règle de calcul de la mémoire.

Autre point : si le nombre de classe est calculé en comptant tous les fichiers .class de l'application y compris ses dépendances, ce n'est pas une source d'information fiable pour les applications Spring qui n'a pas une granularité JAR très fine et charger efficacement juste un petit rapport des classes disponibles sur les fichiers JAR Spring.

Le problème est encore plus visible avec les optimisations que nous avons fournies dans Spring Boot 2.1, et l'optimisation sur laquelle nous travaillons actuellement pour Spring Boot 2.2.

Mon intuition est que les utilisateurs typiques savent combien de Xmx mémoire est requise localement par leur application, et nous devrions peut-être utiliser cette information par défaut.

question

Commentaire le plus utile

Il est possible de fonctionner avec moins de 512M en configurant le calculateur de mémoire.
Le manifeste suivant fonctionne pour moi (spring boot + webflux).

applications:
- name: myapp
  path: target/myapp-0.0.1-SNAPSHOT.jar
  memory: 256m
  env:
    JAVA_OPTS: '-XX:ReservedCodeCacheSize=32M -XX:MaxDirectMemorySize=32M'
    JBP_CONFIG_OPEN_JDK_JRE: '[memory_calculator: {stack_threads: 30}, jre: {version: 11.+}]'

Une application webflux vanille fonctionne en fait avec seulement 60 Mo de RAM.

Je suis un grand fan de la calculatrice de mémoire car la plupart des développeurs ont tendance à ne se soucier que de la taille du tas et d'obtenir un OOME inattendu (par exemple, Metaspace) mais je suis d'accord que nous pourrions l'améliorer.
La taille de fil par défaut (300 ?) dans la calculatrice serait trop grande pour au moins webflux.

Pour les débutants, il est assez difficile de trouver le moyen de personnaliser la taille de la mémoire.
Des exemples de configuration par cas d'utilisation dans README seraient très utiles.

Tous les 8 commentaires

Il est possible de fonctionner avec moins de 512M en configurant le calculateur de mémoire.
Le manifeste suivant fonctionne pour moi (spring boot + webflux).

applications:
- name: myapp
  path: target/myapp-0.0.1-SNAPSHOT.jar
  memory: 256m
  env:
    JAVA_OPTS: '-XX:ReservedCodeCacheSize=32M -XX:MaxDirectMemorySize=32M'
    JBP_CONFIG_OPEN_JDK_JRE: '[memory_calculator: {stack_threads: 30}, jre: {version: 11.+}]'

Une application webflux vanille fonctionne en fait avec seulement 60 Mo de RAM.

Je suis un grand fan de la calculatrice de mémoire car la plupart des développeurs ont tendance à ne se soucier que de la taille du tas et d'obtenir un OOME inattendu (par exemple, Metaspace) mais je suis d'accord que nous pourrions l'améliorer.
La taille de fil par défaut (300 ?) dans la calculatrice serait trop grande pour au moins webflux.

Pour les débutants, il est assez difficile de trouver le moyen de personnaliser la taille de la mémoire.
Des exemples de configuration par cas d'utilisation dans README seraient très utiles.

@making J'ai mis à jour le titre de ce numéro pour qu'il soit plus clair qu'il s'agit de la configuration par défaut qui est sous-optimale pour (au moins) les applications de démarrage. Il est bien sûr tout à fait possible de faire tourner des applications Boot avec 256M et une configuration personnalisée, mais la configuration mémoire par défaut me semble très très loin d'être précise et c'est là que j'aimerais qu'on progresse, car elle impacte beaucoup d'utilisateurs.

Le nombre de threads que vous mentionnez pour l'application WebFlux est en effet un point très intéressant, le build pack pourrait apporter une valeur ajoutée supplémentaire en détectant de quel type d'application il s'agit. Cela peut être délicat car certaines applications MVC peuvent utiliser Reactive WebClient , mais je suis sûr que nous pouvons faire quelque chose de plus intelligent et précis.

Votre configuration de mémoire personnalisée met en évidence IMO que quelque chose ne va pas dans le mécanisme de configuration automatique. Comme expliqué dans https://github.com/cloudfoundry/java-buildpack-memory-calculator/issues/24 , si je spécifie explicitement le nombre de classes (entre 8000 et 10000) effectivement utilisées par les applications de démarrage, le paramètre généré est -XX:ReservedCodeCacheSize=240M , où vous spécifiez -XX:ReservedCodeCacheSize=32M . Cette différence est vraiment énorme, pourrions-nous faire une supposition plus éclairée ?

De plus, 8000 ou 10000 sont le nombre de classes effectivement utilisées par les applications de démarrage. Si le pack de construction calcule cela à partir du nombre de classes dans l'application + dépendances, j'ai tendance à penser que le nombre de classes spécifié au calculateur de mémoire sera artificiellement élevé (je dois encore vérifier la valeur actuellement devinée mais le pack de construction) en raison de la nature des fichiers JAR Spring Framework.

Je me demande également si nous tirons parti des nouvelles options de mémoire de conteneur disponibles dans les derniers Java 8 et Java 11. Elles sont conçues pour Docker, mais je suppose que nous pourrions également en bénéficier dans Cloud Foundry. L'environnement d'exécution Java sait-il que nous fonctionnons dans des conteneurs alors que CF n'utilise pas Docker ? Tirons-nous parti d'options telles que -XX:InitialRAMPercentage , -XX:MaxRAMPercentage ou -XX:MinRAMPercentage ?

C'est un problème délicat @sdeleuze. Le java-buildpack utilise-t-il les valeurs par défaut de Java, que nous supposons que certaines réflexions ont été apportées aux paramètres de Java, permettant aux applications de fonctionner, par défaut, plus comme elles le font lorsqu'elles ne s'exécutent pas dans CF ? Ou le java-buildpack modifie-t-il les valeurs par défaut pour améliorer l'expérience initiale, mais laisse-t-il ensuite les utilisateurs à la recherche de réponses lorsque l'application ne s'exécute pas comme prévu, pas dans CF ?

Aujourd'hui, java-buildpack a choisi d'utiliser les valeurs par défaut java et tomcat en faisant confiance à ces valeurs comme application typique aujourd'hui. Personnellement, j'aime cette approche plus que la modification des paramètres par défaut de Java qui peuvent affecter l'application de manière peu visible/explicite pour l'utilisateur.

En ce qui concerne les nouvelles propriétés, ma compréhension des propriétés RAMPercentage est qu'elles définissent simplement automatiquement des valeurs de tas en fonction d'un pourcentage de RAM disponible. Aucune pensée pour les exigences de mémoire non tas comme la taille du cache de code, la taille de la pile de threads, le méta-espace, la surcharge de mémoire GC, etc. Ce travail reste un exercice pour que l'utilisateur devine combien de mémoire non tas leur application a besoin. J'attends avec impatience le jour où Java pourra simplement gérer correctement tous les pools de mémoire pour maintenir une application dans les contraintes de mémoire d'un conteneur. Mais je soupçonne que nous en sommes encore loin.

En passant, il s'agit de la configuration JAVA_OPTS et jre que j'ai définie pour mes applications dont j'ai besoin pour être stable avec une mémoire faible et la vitesse n'est pas un facteur.

  • J'ai défini MaxMetaSize sur une découverte via le profilage.
    JAVA_OPTS
-Xss256K -Xms1M -XX:+UseSerialGC -Djava.compiler=none -XX:ReservedCodeCacheSize=2496k -XX:MaxDirectMemorySize=1M

jre config

  stack_threads: 20
Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

chrylis picture chrylis  ·  10Commentaires

bingosummer picture bingosummer  ·  4Commentaires

aknobloch picture aknobloch  ·  8Commentaires

pxie picture pxie  ·  20Commentaires

thorntonrp picture thorntonrp  ·  4Commentaires