Java 8 终于支持 Docker!
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java 8 终于支持 Docker!,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含1640字,纯文字阅读大概需要3分钟。
内容图文
Java 8曾经与Docker无法很好地兼容性,现在问题已消失。
请注意:我在本文中使用采用GNU GPL v2许可证的OpenJDK官方docker映像。在Oracle Java SE中,这里描述的docker支持功能在更新191中引入。Oracle在2019年4月更改了Java 8更新的许可证,自Java SE 8 Update 211以来商业使用不再免费。
你是否遇到过在docker中运行的基于JVM的应用程序出现“随机”故障?或者也许是一些奇怪的死机?两者都可能是Java 8(仍广泛使用的)中糟糕的docker支持引起的。
Docker使用控制组(cgroups)来限制资源。在容器中运行应用程序时限制内存和CPU绝对是个好主意――它可以阻止应用程序占用整个可用内存及/或CPU,这会导致在同一个系统上运行的其他容器毫无反应。限制资源可提高应用程序的可靠性和稳定性。它还允许为硬件容量作好规划。在Kubernetes或DC/OS之类的编排系统上运行容器时尤为重要。
问题
JVM可以“看到”系统上的整个内存和可用的所有CPU核心,并确保与资源一致。它默认情况下将最大堆大小(heap size)设置为系统内存的1/4,并将某些线程池大小(比如针对GC)设置为物理核心数量。不妨举例说明。
我们将运行一个简单的应用程序,它消耗尽可能多的内存(可在该网站上找到):
我们在拥有64GB内存的系统上运行,所以不妨检查默认的最大堆大小:
如上所述,它是物理内存的1/4即16GB。如果我们使用docker cgroups限制内存,会发生什么?不妨检查一下:
JVM进程被杀死了。由于它是一个子进程――容器本身幸存下来,但通常当java是容器(PID 1)内的唯一进程时,容器会崩溃。
不妨深入看看系统日志:
像这样的故障调试起来可能很难――应用程序日志中没有任何内容。在AWS ECS之类的托管系统上尤其困难重重。
CPU怎么样?不妨再次检查,运行一个显示可用处理器数量的小程序:
不妨在一个cpu编号设置为1的docker容器中运行它:
不好,这个系统上的确有12个CPU。因此,即使可用处理器的数量限制为1,JVM也会尝试使用12――比如说,GC线程数量由该公式设置:
在拥有N个硬件线程(N大于8)的机器上,并行收集器使用N的固定分数作为垃圾收集器线程的数量。如果N的值很大,该分数约5/8。如果N的值低于8,使用的数字是N。
在我们的情况下:
解决方案
OK,我们现在意识到了这个问题。有解决方案吗?幸运的是,有!
新的Java版本(10及以上版本)已经内置了docker支持功能。但有时升级不是办法,比如说如果应用程序与新JVM不兼容就不行。
好消息:Docker支持还被向后移植到Java 8。不妨检查标记为8u212的最新openjdk映像。我们将内存限制为1G,并使用1个CPU:docker run -ti --cpus 1 -m 1G openjdk:8u212-jdk。
内存:
它是256M,正好是已分配内存的1/4。
CPU:
正如我们想要的那样。
此外,还有几个新的设置:
它们允许微调堆大小――这些设置的含义在StackOverflow的这个优秀答案中已得到了解释。请注意:他们设置的是百分比,而不是固定值。正因为如此,改变Docker内存设置不会破坏任何东西。
如果由于某种原因不想要看到新的JVM行为,可以使用-XX:-UseContainerSupport来关闭。
总结
为基于JVM的应用程序设置正确的堆大小极其重要。如果使用最新的Java 8版本,你可以依赖安全(但非常保守)的默认设置。不需要在docker入口点中使用任何变通办法,也不需要再将Xmx设置为固定值。
使用JVM愉快!
原文:https://www.cnblogs.com/lossingdawn/p/11222918.html
内容总结
以上是互联网集市为您收集整理的Java 8 终于支持 Docker!全部内容,希望文章能够帮你解决Java 8 终于支持 Docker!所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。