从历史上看,HotSpot 在 docker 容器中运行的记录很差,错误地判断了分配的资源(例如 RAM)。不过,情况正在慢慢好转。
OpenJ9 如何与 docker 容器保持一致,以及它在多大程度上了解容器提供的资源(内存、套接字、线程等)
此外,在 JavaOne 2017 演示中提到 OpenJ9 可以跨不同的 OpenJ9 VM 缓存 jit 编译的类。当虚拟机被限制在不同的容器中时(或)如果容器化的 JVM 共享一个 docker 卷,这种共享缓存是否可能?
从历史上看,HotSpot 在 docker 容器中运行的记录很差,错误地判断了分配的资源(例如 RAM)。不过,情况正在慢慢好转。
OpenJ9 如何与 docker 容器保持一致,以及它在多大程度上了解容器提供的资源(内存、套接字、线程等)
此外,在 JavaOne 2017 演示中提到 OpenJ9 可以跨不同的 OpenJ9 VM 缓存 jit 编译的类。当虚拟机被限制在不同的容器中时(或)如果容器化的 JVM 共享一个 docker 卷,这种共享缓存是否可能?
With regards to the Shared Class Cache (SCC), both scenarios are possible. Please see "Using the Class Data Sharing feature" from here for an example of sharing a docker volume. When the JVMs are confined to different containers with no shared volume, it is recommended to build the docker container with the SCC pre-built. You dockerfile will look like this.
FROM adoptopenjdk/openjdk9-openj9:x86_64-alpine-jdk-9.181
RUN mkdir /opt/shareclasses && mkdir /opt/app
COPY japp.jar /opt/app
CMD ["java", "-Xshareclasses:cacheDir=/opt/shareclasses", "-jar", "/opt/app/japp.jar"]
You would then need to build and run the image and commit the resultant container and make that as your base image.
docker build -t japp:latest .
docker run japp
docker commit container_id japp
可以创建共享类缓存并将其包含在 Docker 文件中。
共享类缓存可以在开发或预生产环境中创建,或者在应用程序上运行一些测试时创建。在 Pre-prod 中创建缓存可能更有效,但在构建过程中通过测试来实现它要简单得多。我使用 Spring Boot 应用程序对其进行了测试,即使是任何新生成的 Spring Boot 项目中包含的简单“contextLoads”测试也会产生巨大的差异。
这是一个使用 Maven 进行测试的示例,但相同的 VM 选项也可以用于不同的场景。
1. 在启用共享类缓存的情况下运行测试:
您可以使用 Surefire 插件在 Maven 中完成此操作,我不确定如何使用 Gradle 完成此操作
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-Xquickstart -Xshareclasses:cacheDir=classCache,name=appname -Xscmx32m </argLine>
</configuration>
</plugin>
虚拟机参数:-Xquickstart -Xshareclasses:cacheDir=classCache,name=appname -Xscmx32m
您可以检查printStats subOption 使用了多少缓存大小,如下所示: java -jar -Xshareclasses:cacheDir=classCache,name=appname,readonly, printStats application.jar
2. 将预热缓存添加到 Docker 镜像
在这种情况下,只需将 cacheDir 子选项设置的目录添加到图像中 classCache
ADD classCache classCache
由于这些文件每次都会更改,因此应将 classCache 最后添加到图像中
并使用缓存运行应用程序
ENTRYPOINT exec java -Xquickstart -Xtune:virtualized -Xshareclasses:cacheDir=classCache,name=appname,readonly -jar application.jar
虚拟机参数:-Xquickstart -Xtune:virtualized -Xshareclasses:cacheDir=classCache,name=appname,readonly -jar application.jar
可以使用classCache 和 name 子选项指定缓存,如果没有这些,JVM 可能会创建一个新的缓存文件夹并忽略添加到图像中的那个。
根据我的经验,readonly选项使它更快一点,但这并不是绝对必要的。因为当容器被销毁时这个缓存将被删除,所以没有必要持久化 canges。
-Xquickstart 和 -Xtune:virtualized选项可进一步优化容器中的启动速度