Même en Java 8 [Oracle Blogs Japanese Summary- [Java] Java SE support for Docker CPU and memory limits](https://orablogs-jp.blogspot.com/2017/05/java-se-support-for-docker-cpu- et.html) Dans l'article, après 8u131, pouvez-vous voir container.resource.limit.cpu et container.resource.limit.memory dans une certaine mesure et bien faire? Je pensais que ce n'était pas un bon comportement, alors j'ai étudié la reconnaissance du processeur par java8, java10, java11 (ea) lors de l'exécution avec kubernetes, et la partie pour sécuriser la taille de la mémoire.
En particulier, le comportement de Runtime # availableProcessors, qui affecte l'exécution parallèle de GC (nombre de threads) et le nombre de pools de différents threads parallèles, change-t-il en fonction de la version? Est la partie https://bugs.openjdk.java.net/browse/JDK-8140793 Même si vous le regardez, au 31 juillet 2018, la version corrigée n'a pas encore été publiée, je me demandais donc si une version fonctionnerait correctement.
--Lors de l'exécution d'une application Java avec kubernetes, si vous souhaitez reconnaître correctement le processeur et la mémoire, java10 ou une version ultérieure la reconnaîtra correctement.
Vérifiez les informations de métrique lorsque vous exécutez l'application Spring Boot appropriée et les informations lorsque vous exécutez java -XX: + PrintGCDetails -XX: + PrintFlagsFinal -XX: + UnlockExperimentalVMOptions
sur le conteneur.
Application Spring Boot https://github.com/h-r-k-matsumoto/spring-boot-sample Basé sur, chacun a été modifié comme suit. De plus, l'allocation des ressources au cointainer est la suivante.
020_deployments.yml
resources:
requests:
cpu: 150m
memory: 512Mi
limits:
cpu: 900m
memory: 512Mi
Le texte intégral des déploiements https://github.com/h-r-k-matsumoto/spring-boot-sample/blob/master/kubernetes/020_deployments.yml est.
java8 (no cgroup option) Remplacez l'image de pom.xml par la suivante. En particulier, les options Java ne contrôlent rien. Laissez la valeur par défaut.
pom.xml
<image>openjdk:8u171-jre-alpine</image>
java8 Remplacez l'image de pom.xml par la suivante.
pom.xml
<image>openjdk:8u171-jre-alpine</image>
De plus, ajoutez l'option jvmFlag suivante. Le point est ʻUseCGroupMemoryLimitForHeap`. Le reste ... c'est ce que je porte toujours lorsque je cours dans un environnement docker.
pom.xml
<jvmFlag>-XX:+UnlockExperimentalVMOptions</jvmFlag>
<jvmFlag>-XX:+UseCGroupMemoryLimitForHeap</jvmFlag>
<jvmFlag>-XX:ParallelGCThreads=1</jvmFlag>
<jvmFlag>-XX:CICompilerCount=2</jvmFlag>
<jvmFlag>-Djava.util.concurrent.ForkJoinPool.common.parallelism=1</jvmFlag>
java10 Remplacez l'image de pom.xml par la suivante. Aucune option n'est spécifiée.
pom.xml
<image>openjdk:10-jre-slim</image>
java11 (ea) Remplacez l'image de pom.xml par la suivante. Aucune option n'est spécifiée.
pom.xml
<image>openjdk:11-jre-slim</image>
Métriques Spring Boot Actuator
PrintFlagsFinal
kubectl exec {pod-name} -- java -XX:+PrintGCDetails -XX:+PrintFlagsFinal -XX:+UnlockExperimentalVMOptions
Utilisez les informations obtenues en exécutant.
Spring Boot Actuator - metrics
system.cpu.count
http://pod-ip:port/actuator/metrics/system.cpu.count
Obtenez-le avec. C'est le résultat de l'exécution de Runtime # availableProcessors
.
La source est [micromètre --ProcessorMetrics.java](https://github.com/micrometer-metrics/micrometer/blob/35890bdc64614c24a8117099b0dcdaa003eab798/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/system/binder ProcessorMetrics.java # L83).
jvm.memory.max (heap)
http://pod-ip-port/actuator/metrics/jvm.memory.max?tag=area:heap
Obtenez-le avec. La taille maximale de la zone de tas.
La source est [micromètre --JvmMemoryMetrics.java](https://github.com/micrometer-metrics/micrometer/blob/cff2e23445812852b5fa97b414958dbe595f0ae2/micrometer-core/src/main/java/io/micrometer/inder/jinder/instrument/ /JvmMemoryMetrics.java#L77-L96). C'est le résultat de MemoryUsage # getMax
.
MaxHeapSize La taille de la zone de gestion maximale du tas. Il doit être identique à [jvm.memory.max](# jvm.memory.max? Tag = area: heap).
UseParallelGC S'il faut exécuter GC en parallèle. Référence: https://docs.oracle.com/javase/jp/8/docs/technotes/guides/vm/gctuning/collectors.html
ParallelGCThreads Le nombre de threads pour GC parallèle.
La spécification du nœud à exécuter est vCPUx2 et mémoire 7,5 Go.
java version | system.cpu.count | jvm.memory.max(heap):MiB | MaxHeapSize:MiB | UseParallelGC | ParallelGCThreads |
---|---|---|---|---|---|
java 11(ea) | 1 | 123.75 | 128.00 | false | 0 |
java 10 | 1 | 123.75 | 128.00 | false | 0 |
java 8 | 2 | 120.00 | 128.00 | true | 2 |
java 8 (no cgroup option) | 2 | 1,857.00 | 1,870.00 | true | 2 |
Sauf si une option est spécifiée, java11 et java10 sont calculés correctement à partir de la taille de mémoire 512Mi
allouée aux conteneurs, et MaxRAMFraction = 4, donc 512/4 = 128.
De plus, le processeur est réglé sur 900 m, mais il est considéré comme un cœur.
java11 et java10 semblent fonctionner correctement sur le conteneur sans spécifier Xmx ou Xms.
Dans le cas de java8, vous pouvez contrôler la mémoire. Cependant, concernant le nombre de processeurs, il semble qu'il n'est pas possible de bien faire ... Il semble préférable de définir la partie qui est calculée à partir de Runtime # availableProcessors
et sécurise à chaque fois les ressources dans les propriétés système etc.
Je m'en fiche s'il y a une légère différence entre jvm.memory.max (tas) et MaxHeapSize! Veuillez préciser si vous dites "Il vaut mieux spécifier une telle option" ou "C'est faux".
--FookJoinPool et nombre de spécifications de pool: https://docs.oracle.com/javase/jp/8/docs/api/java/util/concurrent/ForkJoinPool.html#ForkJoinPool--
Recommended Posts