java - Java 微服务、JVM 参数、k8s 和 Docker 的配额和其他
问题描述
假设通过 Docker 和 Kubernetes 部署 Java 微服务(Dropwizard)。
一个示例微服务使用192Mi
HeapSize 完美启动和运行。这被确定为基本内存要求。
一个示例 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 > 10
JVM 会检测它是否在容器中运行。因此,无需像在 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
?有关详细信息,请参阅下面的链接。
所以,现在我的问题:
- 我对上述建议是否正确?
- 您如何确定实现低成本部署的限制?
- 是否需要对 JVM 应用额外的参数,比如
GC
或MaxMetaspaceSize
防止内存使用超过限制? - 我还需要为 Dockerfile 定义 JVM-Args 吗?更清楚一点,Docker 的 JVM 和 Java-Microservice 的 JVM 是一样的吗?
解决方案
您需要使用分析器来分析您的应用程序,并使用 APM 工具对其进行监控,以便在需要时微调内存需求及其持续活动。关于最后一个问题,无论 docker 镜像所具有的 JRE/JDK 是用于在 kubernetes 中为 pod 创建容器的 JDK/JRE。另外我注意到您使用的 JDK 不推荐用于生产部署……而是使用 JRE。
从 Kubernetes 配额的角度要记住的是,在任何时候,如果 java 应用程序的内存消耗超过了限制中定义的值,则 Pod 将被终止。
如果请求中没有定义那么多可用内存的节点,则根本不会调度 pod。
推荐阅读
- python - 从python中的按钮调用时无法使用全局变量
- android - OpenCV 使用 Android 应用程序的静态库
- javascript - PassportJS 验证过期的 JWT
- python - Scrapy spider 的 PyCharm 调试配置引发错误
- c - 为什么我的程序没有告诉字符串数组的最后一个字符是 NULL?
- python - 线程缓冲区崩溃
- python - 如何使用电报机器人创建超链接?
- javascript - 有没有办法在浏览器中使用流媒体来打开/关闭视频流?
- java - OneToMany 的问题包括 spring jpa 中的过滤子句
- azure - 在 Azure 应用配置中设置/添加功能标志