docker设置jvm参数_如何设置Docker容器中Java应⽤的内存
限制
最近在和阿⾥的⼀些同事谈起使⽤Docker部署Java应⽤的场景,其中⼀个⼤家普遍关⼼的问题就是如何设置容器中JVM的内存限制。
如果使⽤官⽅的Java镜像,或者基于Java镜像构建的Docker镜像,都可以通过传递 JAVA_OPTS 环境变量来轻松地设置JVM的内存参数。⽐如,对于官⽅Tomcat 镜像,我们可以执⾏下⾯命令来启动⼀个最⼤内存为512M的tomcat实例
在⽇志中,我们可以清楚地发现设置已经⽣效 “Command line argument: -Xmx512m”
然⽽在Docker集上部署运⾏Java容器应⽤的时候,仅仅对JVM的heap参数设置是不够的,我们还需要对Docker容器的内存资源进⾏限制:
1. 限制容器使⽤的内存的最⼤量,防⽌对系统或其他应⽤造成伤害
2.
能够将Docker容器调度到拥有⾜够空余的内存的节点,从⽽保证应⽤的所需运⾏资源;
关于容器的资源分配约束,Docker提供了相应的启动参数
对内存⽽⾔,最基本的就是通过 -m参数来约束容器使⽤内存的⼤⼩
那么问题就来了,为了正确设置Docker容器内存的⼤⼩,难道我们需要同时传递容器的内存限制和JAVA_OPTS环境变量吗?
如下所⽰:
这个⽅法有两个问题
1. 需要管理员保证容器内存和JVM内存设置匹配,否则可能引发错误
2.
当对容器内存限制调整时,环境变量也需要重新设定,这就需要重建⼀个新的容器
是否有⼀个⽅法,可以让容器内部的JVM⾃动适配容器的内存限制?这样可以采⽤更加统⼀的⽅法来进⾏资源管理,简化配置⼯作。
⼤家知道Docker是通过CGroup来实现资源约束的,⾃从1.7版本之后,Docker把容器的local
cgroups以只读⽅式挂载到容器内部的⽂件系统上,这样我们就可以在容器内部,通过cgroups信息来获取系统对当前容器的资源限制了。
我创建了⼀个⽰例镜像 registry.aliyuncs/denverdino/tomcat:8-autoheap,其源代码可以从Github 获得。它基于Docker官⽅Tomcat镜像创建,它的启动脚本会检查CGroup中内存限置,并计算JVM最⼤Heap
size来传递给Tomcat。其代码如下
说明:
为了监控,故障排查等场景,我们预留了部分内存(缺省64M),其余容器内存我们都分配给JVM的堆。
这⾥没有对边界情况做进⼀步处理。在⽣产系统中需要根据情况做相应的设定,⽐如最⼤的堆⼤⼩等等。
docker重启容器命令现在我们启动⼀个tomcat运⾏在512兆的容器中
通过下列命令,从⽇志中我们可以检测到相应的JVM参数已经被设置成 448MB (512-64)
我们也可以⽅便的调整Java应⽤的内存.
Docker
1.10提供了对容器资源限制的动态修改能⼒。但是由于JVM⽆法感知容器资源修改,我们依然需要重启tomcat来变更JVM的内存设置,例如,我们可以通过下⾯命令把容器内存限制调整到1GB
再次检查⽇志,相应的JVM Heap Size最⼤值已被设置为960MB
阿⾥百川(baichuan.taobao)是阿⾥巴巴集团“云”
“端”的核⼼战略是阿⾥巴巴集团⽆线开放平台,基于世界级的后端服务和成熟的商业组件,通过“技术、商业及⼤数据”的开放,为移动创业者提供可快速搭建App、商业化APP并提升⽤户体验的解决⽅案;同时提供多元化的创业服务-物理空间、孵化运营、创业投资等,为移动创业者提供全⾯保障。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论