乐趣区

关于后端:让JVM感知K8s资源限制

无感知导致的问题

当咱们在 K8s 中 Deployments 配置资源限度和预留的时候,比方设置最大内存为 500M。然而宿主机的总内存为 8G,这时候 Pod 启动后会超出内存限度,被 Deployments 杀掉。但为了保护设置的正本数量又创立新的,如此重复。

起因是默认状况 JVM 默认最大堆空间为零碎总内存的 1 /4,在容器中没有感知到集群为 Pod 设置的资源限度,而是按宿主机的内存算的,所以最终超过限度内存。

解决方案

解决思路有两种:

  • 一种是按资源限度算好,在 Java 启动参数中设置堆内存大小,保障不超限度
  • 另一种是让 JVM 感知到容器资源限度,按这个值来分配内存

Java SE 8u131 向后 和 JDK 9 都有参数反对:如下

-XX:+UnlockExperimentalVMOptions 
-XX:+UseCGroupMemoryLimitForHeap

然而如果资源限度默认调配 1 / 4 有点节约,因为个别一个 Pod 就跑这一个次要过程,所以能够改下这个默认值,如下:

# 2 代表 1 /2
-XX:MaxRAMFraction=2

这样配置并不代表就是资源限度的 1 /2,因为除了堆内存还有其余堆外内存须要空间,所以理论值要远小于 1 /2。网上有人在测试环境设置 1,代表 100%,然而我试过之后还是超过资源限度了,所以选了 2,理论须要依据状况决定。

参考连贯

Java SE support for Docker CPU and memory limits

测试例子

退出移动版