容器上的JVM调优(Java 8)

容器上的JVM调优(Java 8),java,docker,tomcat,jvm,amazon-ecs,Java,Docker,Tomcat,Jvm,Amazon Ecs,我们最近将应用程序堆栈从EC2迁移到ECS-EC2,我们的计划是将ECS-EC2堆栈迁移到生产环境中。 我们一直面临在ECS容器上调整应用程序的问题。我们在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/

我们最近将应用程序堆栈从EC2迁移到ECS-EC2,我们的计划是将ECS-EC2堆栈迁移到生产环境中。 我们一直面临在ECS容器上调整应用程序的问题。我们在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的软内存)

我们到目前为止所做的-

我在互联网上看到了许多帖子,主题是“没有人把java放在容器上”。 因此现在升级到tomcat image 8.5.40,它使用开放jdk“1.8.0_212”(向后支持容器)。 但是在使用上述Dockerfile之后,当我们在容器中运行命令
java-XX:+UnlockDiagnosticVMOptions-XX:+PrintFlagsFinal
时,它不会显示与我们在java\u OPTS变量中的Dockerfile中提供的JVM调优值相同的值(MaxHeap、MinHeap、GC、ParallelGCThreads和其他)

我在Docker容器中本地尝试了类似的方法,但同样的问题正在发生

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


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

在docker内部运行JVM时,必须使用以下参数指定虚拟机可以从总可用内存中占用的内存量:

-XX:+UseContainerSupport

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


关于GC,您必须查看在该映像上运行的JVM构建。可能该版本不允许您指定G1 GC(您可以在此处查看原因)

谁进行了上一次调优?@ThorbjørnRavnAndersen我们使用相同的调优配置,但它与EC2一起工作,而不是容器化。尝试删除它以查看JVM的性能。也考虑升级到java 11,它更易于容器友好。@ Thorbj java RNRavnDeNeRSEN我尝试删除除启动日志在<代码> Calalina。日志< /代码>,在输出中没有影响<代码> javaXX:+unCalkHythCypVMSEPTOS:XX:+PrrtFraseReals< /Cord>。我一直在升级到Java 11作为最后一个选项,因为它可能会影响内部依赖性(需要努力)。
UseContainerSupport
已经在Java 8u191+上启用,因此我使用的是开放jdk“1.8.0212”。默认情况下,此变量处于启用状态。我已经尝试过给予这个选择,但没有运气。容器上没有考虑任何JVM调优选项(我在docker文件中给出的所有选项)(根据
java-XX:+UnlockDiagnosticVMOptions-XX:+PrintFlagsFinal
)我也尝试过,提到
-XX:MaxRamPercentage
但它通过
java-XX:+UnlockDiagnosticVMOptions-XX:+PrintFlagsFinal
显示默认值25.000000,我在您的Dockerfile中看到您有这个ENV java\u 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环境变量中