尝试使用 docker 部署容器化的springboot应用。 这是我的 Dockerfile :
ROM openjdk:8
ADD app-1.0.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-Xmx64m", "-Xss256k", "-jar", "ecalio-landing.jar"]
并运行这样的容器:
sudo docker run -d -m256m --restart=always server.tomcat.max-threads=5 --name=ecalio-landing
一旦部署,我就使用 Apache基准来测试 后端以及请求量< / strong>,它可以使用以下命令到达:
ab -n 20000 -c 10 http://www.ecalio.com/
基本上,试图知道后端是否一次可以达到20000个请求10,因为我已限制了容器内存消耗为 256mb 。
容器以开始, 220mb ,并且到达,达到水平的245mb ,并且 ,即使我重新运行了 ab命令
但是,当我尝试使用浏览器到达后端时,每次刷新浏览器都会消耗 0.1mb ,显然容器一旦达到内存消耗256mb ,便会崩溃。
这种事情怎么发生 ?
我不希望我的容器消耗大量内存,它基本上是一个简单的应用,它结合了 jpa 和 1个实体 <仅使用strong>模型,并且每次使用简单的控制器( @Controller ),然后返回由百里香
呈现的单个HTML页面我将Java VisualVM与我的应用程序一起使用(在没有docker容器的情况下在我的计算机上本地启动),并且我可以清楚地看到我的应用程序没有任何内存泄漏,堆内存的扩展范围不超过68mb和用过的堆总是被GC清除...
答案 0 :(得分:0)
经过这么多努力,我找到了解决方案,这太荒谬了...
当这两个选项没有传递给JVM时,它假定即使将-m参数传递给容器的创建命令,该容器也与主机共享相同的资源量。
-XX:+UnlockExperimentalVMOptions
-XX:+UseCGroupMemoryLimitForHeap
这意味着如果我使用-m300m创建一个容器以指定我的容器不应分配超过300mb,则jvm仍会认为该容器有权使用2gb的内存(其中2gb是本机的物理内存)
使用这些选项,我可以使我的应用程序在256mb的容器上工作...当我知道有一次,我的容器消耗了800mb的空间时,真是太神奇了。
来源:
Official openjdk's docker image
我的新Dockerfile:
FROM openjdk:8
ADD app.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-server", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseCGroupMemoryLimitForHeap", "-jar", "app.jar"]
-server
有助于让JVM知道该应用程序将在服务器环境中被执行,这将导致某些变化,包括针对服务器环境的GC专用算法以及一些其他行为,这些行为可能会在官方文档。
请注意,不需要Xmx或Xss或任何其他用于内存限制的选项,因为JVM会自行修复所有问题(下面的文章中有更多详细信息)
要知道的另一件事是,此配置是在OpenJDK 11中自动完成的。