最新消息:

Java in Docker and Kubernetes

Linux ipcpu 3415浏览

运行在Docker或者Kubernetes中的JAVA程序如何正确获取CPU和内存的限制

零、概述

Docker容器利用CGroup对进程使用的资源进行限制,而在容器中的JVM依然会利用宿主机环境的内存大小和CPU核数进行缺省设置,这导致了JVM Heap的错误计算。JVM缺省的GC、JIT编译线程数量取决于宿主机CPU核数。如果我们在一个节点上运行多个Java应用,即使我们设置了CPU的限制,应用之间依然有可能因为GC线程抢占切换,导致应用性能受到影响。

那么我们来看下各个版本JDK如何使用docker的限制。

一、JDK老版本

1、使用环境变量,直接指定JVM堆大小 -e JAVA_OPTIONS='xMX300m'
2、明确GC和JIT并行线程数目,以避免二者占用过多资源。

-XX:ParallelGCTreads
-XX:CICompilerCount

注意ParallelGCThreads的计算方法:

ParallelGCThreads = (ncpus <= 8) ? ncpus : (8 + ((ncpus - 8) * 5) / 8);
#cpu核数小于等于8,取核数;cpu核数大于8按后面公式计算

二、 JDK 8u131+(backported)

使用以下JVM参数,适配docker容器的内存,CPU可能无法获取限制,需要手动设置

-XX:+UnlockExperimentalVMOptions 
-XX:+UseCGroupMemoryLimitForHeap

三、 JDK 8u191+(backported)

默认开启了UseContainerSupport,支持容器内部获取CPU和内存限制。

-XX:UseContainerSupport

并增加了ActiveProcessorCount参数指定CPU数量

-XX:ActiveProcessorCount=count

四、 JDK9 、JDK10

不是LTS(长期支持)版本

五、 JDK11+

默认开启了UseContainerSupport,支持容器内部获取CPU和内存限制。

-XX:UseContainerSupport

并增加了ActiveProcessorCount参数指定CPU数量

-XX:ActiveProcessorCount=count

参考资料

https://www.jishuwen.com/d/2K0J#tuit
https://segmentfault.com/a/1190000013945253
https://royvanrijn.com/blog/2018/05/java-and-docker-memory-limits/
https://bufferings.hatenablog.com/entry/2018/11/11/114534
https://www.oracle.com/technetwork/java/javase/8u191-relnotes-5032181.html#JDK-8146115

 

 

转载请注明:IPCPU-网络之路 » Java in Docker and Kubernetes