共计 2162 个字符,预计需要花费 6 分钟才能阅读完成。
原文地址:https://blog.lanweihong.com/p…
前言
在微服务架构中,网关、注册核心、配置核心、服务追踪、认证核心等一系列组件部署到服务器中会占用肯定的内存,还有各个业务服务,一部署单个服务可能就占个几百 M,甚至上 G。那这一系列组件和服务同时部署不得耗费更多的内存?为避免这些服务把系统资源耗尽导致宕机,咱们不得不为这些服务配置肯定的内存限度。
在 k8s 环境中,如果咱们单单配置了 memory
的 limit,没有配置 Java 利用的 JVM 参数,那么在 Java 程序运行过程中可能会导致内存超过 memory
的 limit,发送 OOM 谬误。因而,部署 Java 利用到 k8s 环境中时要配置 JVM 参数及 k8s 的 memory
limit。
JVM 参数配置办法
随着 JAVA 版本不同,有不同的解决办法,如下表:
JDK 版本 | JVM 参数 |
---|---|
<8u131 | -Xms64m -Xmx128m |
8u131-191 | -XX:+UnlockExperimentalVMOptions 、-XX:+UseCGroupMemoryLimitForHeap |
>8u191 | -XX:UseContainerSupport (默认启用)、ActiveProcessorCount ;百分比调配堆内存:MaxRAMPercentage 、InitialRAMPercentage 、MinRAMPercentage |
JDK8 版本小于 131 时,启动 JAVA 程序时,增加参数 -Xms64m -Xmx128m
;java 8u131+ 和 java 9+ 版本,增加两个参数:-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap
;JDK8 版本高于 191 时,能够应用 MaxRAMPercentage
,MaxRAMPercentage
值介于 0.0 到 100.0 之间,默认值为 25.0。
配置
JDK 版本 8u131
在 Dockerfile
文件中配置:
ENV JVM_OPTS -Xms256m -Xmx512m
ENTRYPOINT exec java $JVM_OPTS -jar lanweihong.jar
留神这两个参数只设置了调配给堆的大小,理论的 memory limit 应该比这个还要大。
java 8u131+ 和 java 9+ 版本
对于 java 8u131+ 和 java 9+ 版本,在 Dockerfile
文件中,设置环境变量:
ENV JVM_OPTS -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=2
ENTRYPOINT exec java $JVM_OPTS -jar lanweihong.jar
其中 -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap
设置 -XX:MaxRAM
为 cgroup 的内存限度,这里的 -XX:MaxRAMFraction
值为 2,那么 JVM 容许调配的内存为 MaxRAM / MaxRAMFraction = 4G / 2 = 2G
,不设置为 1 是避免 JVM 占用所有的内存,导致其余过程(如 Shell、MySQL 等) 没有可用内存。
JDK 版本 8u191+
在 Dockerfile
文件中配置:
ENV JVM_OPTS -XX:MaxRAMPercentage=80.0
ENTRYPOINT exec java $JVM_OPTS -jar lanweihong.jar
设置 JVM 可用的内存为总内存的 80%,显然这种形式更加灵便不便,也更平安。
如果应用 jib-maven-plugin
打包的,能够在 pom.xml
中增加配置:
...
<container>
<mainClass>com.lanweihong.gateway.GatewayApplication</mainClass>
<!-- 增加 jvm 参数 -->
<jvmFlags>
<jvmFlag>-XX:MaxRAMPercentage=80.0</jvmFlag>
</jvmFlags>
</container>
...
执行成果等同于 java -XX:MaxRAMPercentage=80.0 ...
k8s 配置
设置内存 limit;在 k8s 部署配置文件增加:
containers:
resources:
requests:
memory: "512Mi"
# cpu: "500m"
limits:
memory: "512Mi"
# cpu: "500m"
env:
- name: JVM_OPTS
values: -XX:MaxRAMPercentage=80.0
应用 kubectl apply -f
更新公布服务。
总结
- JDK8 版本低于 191 的倡议降级到最新版本,或 191 当前,Java 8u191 和 Java 10+ 反对
UserContainerSupport
,设置 JVM 启动参数MaxRAMPercentage
,具体的值依据状况来设置; - 不降级 JDK 版本的,依据 JDK 版本按以上阐明配置;
- Kubernetes 配置 Limit。
参考文档
- How To Configure Java Heap Size Inside a Docker Container
- Kubernetes_pod_javajdk_动静 JVM 堆内存大小限度