【发布时间】:2019-10-20 03:52:32
【问题描述】:
我在 AWS Fargate 服务的 docker 容器中启动我们的 Spring Boot 应用程序,因此一旦 CPU 消耗达到 100% 以上,容器就会停止 Docker OOM-killer 并出现错误
原因:OutOfMemoryError:容器因内存使用而被杀死
在指标上,我们可以看到 CPU 变得超过 100%。经过一段时间的分析,我们似乎发现了消耗 CPU 的代码,但我的问题是,CPU 怎么能超过 100%?
是不是说 JVM 只使用了 100%?
我记得我们在内存消耗方面遇到过类似的问题。看了很多关于cgroups的文章,发现解决方法是指定
-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap
因此,当您使用选项 -m=512 启动 docker 时,堆大小将是 mac 大小的 1/4。堆大小也可以通过选项调整
-XX:MaxRAMFraction=2
这将为堆分配 1/2 的 docker 内存。 我应该对 CPU 使用类似的东西吗? 我读了文章https://blogs.oracle.com/java-platform-group/java-se-support-for-docker-cpu-and-memory-limits,但它告诉我们
从 Java SE 8u131 开始,在 JDK 9 中,JVM 支持 Docker 透明地尊重 Docker CPU 限制。这意味着如果 -XX:ParalllelGCThreads 或 -XX:CICompilerCount 未指定为命令行选项,JVM 将应用 Docker CPU 限制作为 JVM 在系统上看到的 CPU 数量。然后JVM会调整 GC 线程和 JIT 编译器线程的数量就像它一样 就好像它在设置了 CPU 数量的裸机系统上运行一样 作为 Docker CPU 限制。
Docker命令用来启动
docker run -d .... -e JAVA_OPTS='-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:+PrintFlagsFinal -XshowSettings:vm' -m=512 -c=256 ...
使用Java版本
openjdk version "1.8.0_181"
OpenJDK Runtime Environment (build 1.8.0_181-8u181-b13-1~deb9u1-b13)
OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode)
启动过程中有关应用程序的一些附加信息
VM settings:
Max. Heap Size (Estimated): 123.75M
Ergonomics Machine Class: client
Using VM: OpenJDK 64-Bit Server VM
ParallelGCThreads = 0
CICompilerCount := 2
CICompilerCountPerCPU = true
【问题讨论】:
标签: java amazon-web-services docker aws-fargate