关于java:JavaSpring应用在k8s环境中的内存配置实践

8次阅读

共计 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;百分比调配堆内存:MaxRAMPercentageInitialRAMPercentageMinRAMPercentage

JDK8 版本小于 131 时,启动 JAVA 程序时,增加参数 -Xms64m -Xmx128m;java 8u131+ 和 java 9+ 版本,增加两个参数:-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap;JDK8 版本高于 191 时,能够应用 MaxRAMPercentageMaxRAMPercentage 值介于 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 更新公布服务。

总结

  1. JDK8 版本低于 191 的倡议降级到最新版本,或 191 当前,Java 8u191 和 Java 10+ 反对 UserContainerSupport,设置 JVM 启动参数 MaxRAMPercentage,具体的值依据状况来设置;
  2. 不降级 JDK 版本的,依据 JDK 版本按以上阐明配置;
  3. Kubernetes 配置 Limit。

参考文档

  1. How To Configure Java Heap Size Inside a Docker Container
  2. Kubernetes_pod_javajdk_动静 JVM 堆内存大小限度

正文完
 0