第三十一章、Java程序运行在Docker等容器环境的问题

对于java来说,Docker毕竟是一个较新的环境,例如,其内存、CPU等资源限制是通过CGroup实现的,早期的JDK版本并不能识别这些限制,进而会导致一些基础问题:

    1、如果未配置合适的JVM堆和元数据区、直接内存等参数,java就有可能试图使用超过容器限制的内存,最终被容器OOM kill,或者自身发生OOM。

    2、错误判断了可获取的CPU资源,例如,Docker限制了CPU的核数,JVM就可能设置不合适的GC并行线程数等。

从应用打包、发布等角度出发,JDK自身就比较大,生成的镜像就更为臃肿,当我们的镜像非常多的时候,镜像的存储等开销就比较明显了;

如果考虑到微服务、Serverless等新的架构和场景,java自身的大小、内存占用、启动速度,都存在一定局限性,因为java早期的优化大多是针对长时间运行的大型服务器端应用。


Docker和虚拟机的区别?

虽然Docker之类的容器和虚拟机非常相似,例如,它也有自己的shell,能独立安装软件包,运行时与其他容器互不干扰。但是,如果深入分析会发现,Docker并不是一种完全的虚拟化技术,而更是一种轻量级的隔离技术。


虚拟机与docker的区别

Docker未每个容器提供了单独的命名空间,堆网络、PID、用户、IPC通信、文件系统挂载点等实现了隔离。对于CPU、内存、磁盘IO等计算资源,则是通过CGroup进行管理。Docker仅在类似linux内核之上实现了有限的隔离和虚拟化,并不是像传统虚拟化软件那样,独立运行一个新的操作系统。如果是虚拟化的操作系统,不管是java还是其他程序,只要调用的是同一个系统API,都可以透明地获取所需的信息,基本不需要额外的兼容性改变。容器虽然省略了虚拟操作系统的开销,实现了轻量级的目标,但也带来了额外复杂性,它限制对于应用不是透明的,需要用户理解Docker的新行为。


对于java平台来说,Docker没有隐藏的底层信息带来了很多意外的困难,主要体现在几个方面:

1、容器环境对于计算资源的管理方式是全新的,CGroup作为相对比较新的技术,历史版本的java显然斌不能自然地理解相应的资源限制;

2、namespace对于容器内的应用细节增加了一些微妙的差异,比如jcmd、jstack等工具会依赖于“/proc//”下面提供的部分信息,但是Docker的设计改变了这部分信息的原有结构,我们需要堆原有工具进行修改以适应这种变化。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Docker — 云时代的程序分发方式 要说最近一年云计算业界有什么大事件?Google Compute Engi...
    ahohoho阅读 15,691评论 15 147
  • 转载自 http://blog.opskumu.com/docker.html 一、Docker 简介 Docke...
    极客圈阅读 13,575评论 0 120
  • 写这篇文章主要是为了今后毕业论文素材上的整理,同时对docker进行巩固温习。大纲: docker简介docker...
    胡图仙人阅读 12,167评论 2 96
  • 尽管知道周日有小雨,一家四口一大早还是带着侥幸的心理出发了,一路上雨没有停下来的意思,反而有愈下愈大的感觉。心中满...
    幸福人生云阅读 3,452评论 0 0
  • nimenjiuzheyanglail
    石猴阅读 1,144评论 0 1