首页 > 解决方案 > Java 微服务、JVM 参数、k8s 和 Docker 的配额和其他

问题描述

假设通过 Docker 和 Kubernetes 部署 Java 微服务(Dropwizard)。

一个示例微服务使用192MiHeapSize 完美启动和运行。这被确定为基本内存要求。

一个示例 Dockerfile,使用openjdk-runtime:11-hotspot

FROM some-container-reg/openjdk-runtime:11-hotspot
# prepare build
COPY --chown=1001:1001 build/install/svc-example .
COPY --chown=1001:1001 config.yml .
# exposing port(s)
EXPOSE 8080
# setting entry point...
ENTRYPOINT ["bin/svc-example", "server", "config.yml"]

注意: 因为使用openjdk > 10JVM 会检测它是否在容器中运行。因此,无需像在 Java 8 中那样启用实验性 VM 功能来实现此目的。有关详细信息,请参阅下面的链接。

https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8146115

对应的k8s部署

resources:
  limits:
    cpu: 250m
    memory: 288Mi 
  requests:
    cpu: 100m
    memory: 192Mi
env:
  - name: JAVA_OPTS
    value: "-XX:MaxRAMPercentage=75.0"

容器请求等于来自 java 应用程序本身的工作量。限制被定义为请求加上偏移量96Mi。通过这样做,我想确保除了 JVM-Heap 之外的需求有足够的资源来正常工作 - MetaspaceSize, CodeCache, ....

JAVA_OPTS通过应用在容器部署-XX:MaxRAMPercentage=75.0中定义,其中定义了 JVM 总内存的 75% 的限制。为什么不在 内定义明确的堆限制-XX:Xmx=192Mi?有关详细信息,请参阅下面的链接。

https://bugs.openjdk.java.net/browse/JDK-8186315

所以,现在我的问题:

标签: javadockerkubernetesjvm

解决方案


您需要使用分析器来分析您的应用程序,并使用 APM 工具对其进行监控,以便在需要时微调内存需求及其持续活动。关于最后一个问题,无论 docker 镜像所具有的 JRE/JDK 是用于在 kubernetes 中为 pod 创建容器的 JDK/JRE。另外我注意到您使用的 JDK 不推荐用于生产部署……而是使用 JRE。

从 Kubernetes 配额的角度要记住的是,在任何时候,如果 java 应用程序的内存消耗超过了限制中定义的值,则 Pod 将被终止。

如果请求中没有定义那么多可用内存的节点,则根本不会调度 pod。


推荐阅读