【发布时间】:2018-06-20 08:39:55
【问题描述】:
在docker中部署应用的原则是什么?
我看到了两个概念
- 为每个应用版本创建图像
- 创建应用程序二进制文件并以某种方式将它们部署到容器(利用即 Tomcat 热部署)
也许还有其他的,我个人喜欢第一个,但如果你经常发布的话,我肯定有大量的数据。一个人如何选择一个而不是另一个?
我想知道其他人如何部署他们的 java 应用程序,以便发表我的个人意见。
【问题讨论】:
在docker中部署应用的原则是什么?
我看到了两个概念
也许还有其他的,我个人喜欢第一个,但如果你经常发布的话,我肯定有大量的数据。一个人如何选择一个而不是另一个?
我想知道其他人如何部署他们的 java 应用程序,以便发表我的个人意见。
【问题讨论】:
2019 年更新:见“Docker memory limit causes SLUB unable to allocate with large page cache”
我在去年 5 月(2019 年)的“Docker support in Java 8 — finally!”中提到,Java 10 的新演变,在 Java 8 中向后移植,意味着 Docker 将更准确地报告使用的内存。
作为mbluke 添加in the comments:
资源问题已在 Java 的更高版本中得到解决。
从 Java SE 8u131 和 JDK 9 开始,JVM 透明地了解 Docker CPU 限制。
从 Java JDK 8u131+ 和 JDK 9 开始,有一个实验性的 VM 选项允许 JVM 人体工程学从 CGgroups 读取内存值。
要启用它,您必须在 JVM 上显式设置参数-XX:+UnlockExperimentalVMOptions和-XX:+UseCGroupMemoryLimitForHeap,Java 10 默认设置了这些参数,不需要这些标志。
2018 年 1 月:原始答案
作为权衡取舍,这取决于您的情况/发布周期。
但也要考虑到 Java 可能首先不适合 docker 环境,这取决于它的性质。
见“Nobody puts Java in a container”
所以我们已经完成了基于 JVM 的应用程序的开发,现在将它打包成一个 docker 镜像并在我们的笔记本上进行本地测试。一切都很好,所以我们将该容器的 10 个实例部署到我们的生产集群上。突然之间,应用程序受到限制,并且没有达到我们在测试系统上看到的相同性能。而我们的测试系统甚至是这个64核的高性能系统……
发生了什么事?
为了允许多个容器并行运行隔离,我们将其指定为限制为一个 cpu(或 CPU 份额的等效比率)。不幸的是,JVM 将看到该节点上的内核总数 (64) 并使用该值来初始化我们之前看到的默认线程数。开始时有 10 个实例,我们最终得到:
10 * 64 Jit Compiler Threads
10 * 64 Garbage Collection threads
10 * 64 ….
而我们的应用程序,受限于它可以使用的 cpu 周期数,主要是处理不同线程之间的切换,并不能完成任何实际工作。
突然间,容器的承诺“打包一次,随处运行”似乎被违反了……
那么具体来说,如何处理每次发布构建映像时生成的数据量?如果每次都在 tomcat 镜像上构建应用,存储镜像所需的磁盘空间会快速增长,对吧?
2 种技术:
【讨论】: