【问题标题】:JVM Tuning on Container (Java 8)容器上的 JVM 调优 (Java 8)
【发布时间】:2020-11-23 23:38:37
【问题描述】:

我们最近将我们的应用程序堆栈从 EC2 迁移到 ECS-EC2,我们的计划是将 ECS-EC2 堆栈迁移到生产环境。 我们在调整 ECS-Container 上的应用程序时遇到了问题。我们在我们的 java web 应用程序中使用 tomcat。 Dockerfile 配置 -

FROM tomcat:8.5.40-jre8
COPY checkout.war /usr/local/tomcat/webapps/
COPY server.xml /usr/local/tomcat/conf
COPY context.xml /usr/local/tomcat/conf
COPY catalina.sh /usr/local/tomcat/bin
ENV spring.profiles.active beta
ENV JAVA_OPTS="-Dspring.profiles.active=beta"
RUN echo "export JAVA_OPTS=\"$JAVA_OPTS -Djava.awt.headless=true -server -Xms12G -Xmx12G -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:ParallelGCThreads=20 -XX:ConcGCThreads=5 -XX:InitiatingHeapOccupancyPercent=60 -XX:+UseStringDeduplication\"" >> /usr/local/tomcat/bin/setenv.sh
CMD ["sh", "-c", "catalina.sh run"]

关于我们的应用程序堆栈的一些信息 - 我们使用 r5.xlarge 实例类型 在 ECS-EC2 中运行 4 个服务,并且没有为任务提供硬内存限制(我们只提供了每个任务需要 2GB 的软内存)。

到目前为止我们做了什么 -

我在互联网上看到很多帖子,主题是“Nobody puts java on containerExample。 因此,现在升级到使用 open jdk "1.8.0_212" 的 tomcat 映像 8.5.40(对容器的向后支持)。 但是使用上述 Dockerfile 后,当我们在容器内运行命令 java -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal 时,它不会显示与我们提供的 JVM Tuning(MaxHeap、MinHeap、GC、ParallelGCThreads 和其他)相同的值。JAVA_OPTS 变量中的 Dockerfile 中。

我在本地的 Docker Container 中尝试过类似的事情,但出现了同样的问题。

如何在使用 Tomcat 服务器 (Java 8) 的基于 docker 容器的应用程序上进行 JVM 调优?任何帮助将不胜感激。

PS : Tomcat 确实会在 catalina.logs 文件的启动时打印 JAVA_OPTS 配置。

【问题讨论】:

  • 之前的调优是谁做的?
  • @ThorbjørnRavnAndersen 我们使用相同的调优配置,但它适用于 EC2,而不是容器化。
  • 尝试删除它以查看 JVM 的执行情况。还可以考虑升级到对容器更友好的 Java 11。
  • @ThorbjørnRavnAndersen 我尝试将它删除,除了catalina.logs 的启动日志,java -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal 的输出没有任何影响。我一直在升级到 Java 11 作为最后一个选项,因为它可能会影响内部依赖(需要努力)。

标签: java docker tomcat jvm amazon-ecs


【解决方案1】:

当您在 docker 中运行 JVM 时,您必须使用以下参数来指定虚拟机可以从总可用内存中占用多少内存:

-XX:+UseContainerSupport

-XX:MaxRAMPercentage=70.0(此标志表示 JVM 可以从 docker 映像内存中获取最大 70%。默认情况下,此值为 25%)

关于 GC,您必须查看在该映像上运行的 JVM 构建。也许那个构建不允许你指定 G1 GC(你可以在这里看看为什么https://bugs.openjdk.java.net/browse/JDK-8148175

【讨论】:

  • UseContainerSupport 已经在 J​​ava 8u191+ 上启用,因此我使用的是 open jdk '1.8.0_212'。此变量默认打开。我已经尝试过提供此选项,但没有运气。容器上不考虑任何 JVM 调整选项(我在 docker 文件中给出的所有选项)(根据 java -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal
  • 我也试过了,提到-XX:MaxRamPercentage,但它通过java -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal显示默认25.000000
  • 我在你的 Dockerfile 中看到你有这个 ENV JAVA_OPTS="-Dspring.profiles.active=beta"。将其替换为 ENV JAVA_OPTS="$JAVA_OPTS -Dspring.profiles.active=beta"
  • 我试过了,但没有成功,JAVA_OPTS 是标准环境变量,直到该行没有任何值。
  • 当你执行java -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal,然后你用默认参数启动一个新的JVM。尝试在您的 docker 映像上执行此命令: java -XX:MaxRAMPercentage=70.0 -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal 并查看结果。如果您看到正确的设置,则将 -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal 添加到您的 JAVA_OPTS 环境变量
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-11
  • 1970-01-01
  • 1970-01-01
  • 2019-02-22
  • 1970-01-01
  • 2014-05-16
  • 2014-05-08
相关资源
最近更新 更多