Java 使用Docker时经常遇到的五个问题_java

  Docker现在很火,容器技术看上不无所不能,但这实际上是一种误解,不要被炒作出来的泡沫迷住双眼,本文抛去炒作,理性地从Java程序员的角度,列举出Docker目前的五大误区,帮助你更好地理解Docker的优势和问题。

  抛去那些媒体和厂商们的炒作,我们如何才能更好更理性的使用Docker? 

 

  Docker最近备受关注,原因显而易见。如何成功交付代码一直困扰着大家。传统的容器技术在众多需求和模板中乱成一团。而Docker可以简单且 重复的创建容器。相比其它容器,使用Docker可以更快、更自然的交付代码。Duang,Docker火了!随之而来也有一些误解和误区。不要太相信别 人说Docker好用或者不好用。自己理性地全面思考一下Docker,会帮助你真正理解是否真的需要它。

  本文列举了从Java角度的五大Docker误读。不过首先介绍些背景知识。为了更好地理解Docker,我们咨询了Fewbytes的Avishai Ish-Shalom,他有丰富的Docker经验,也是DevOps Days会议的组织者。我们和他一起列举出了这些误解。

  主要误区

  1. Docker是轻量级虚拟机

  这是大家初学Docker时最主要的误解。这种误解倒也情有可原,Docker的确看上去有点像虚拟机。Docker网站上甚至有人比较了Docker和虚拟机的区别。但是,Docker实际上不是轻量级虚拟机,而是改进了的Linux容器(LXC)。Docker和虚拟机是完全不一样的,如果你把Docker容器当成轻量级虚拟机来用,会遇到很多问题。

  在使用Docker之前,必须了解Docker容器和虚拟机有很多本质的区别。

  资源隔离:Docker达不到虚拟机所能提供的资源隔离水平。虚拟机的资源是高度隔离的,而Docker从设计之初就需要共享一些资源,这些资源是Docker无法隔离和保护的,比如页缓存和内核熵池。(注:内核熵池很有趣,它收集并且存储系统操作生成的随机比特。机器在需要随机化时会使用这个池,比如密码相关。)如果Docker容器占用了这些共享资源,那么其它进程在这些资源被释放前只能等待。

  开销:大多数人都知道虚拟机的CPU和RAM能提供类似物理机的性能,但是有很多额外的IO开销。因为放弃了虚拟机的guest OS,Docker的package更小,比起虚拟机需要更少的存储开销。但这并不意味着Docker没有任何开销问题。Docker容器依然需要注意 IO开销的问题,只不过没有虚拟机严重而已。

  内核使用:Docker容器和虚拟机在内核使用上完全不同。每个虚拟机使用一个内核。Docker容器则是在所有容器间共享内核。共享内核带来一些 效率的提升,但是以高可用和冗余为代价。如果虚拟机发生了内核崩溃,只有这个内核上的虚拟机会受影响。而Docker容器如果内核崩溃了,所有的容器都会 受影响。

  2. Docker使得应用可扩展

  因为Docker可以在很短的时间内在多个服务器上部署代码,自然有人会觉得Docker可以让应用自身变得可扩展。不幸的是,这是错误的。代码是 应用的基石,而Docker并不会重写代码。应用的可扩展性依然取决于程序员。使用Docker并不会自动得让你的代码易于扩展,只是让这些代码更容易跨 服务器部署而已。

  3. Docker在生产环境广为使用

  因为Docker势头正劲,很多人便认为Docker可以在生产环境上大规模使用。事实上,这是不对的。注意Docker还是很新的技术,还不成 熟,正在成长,这意味着还有很多烦人的bug和待完善的功能。对新技术感兴趣这没错,但是最好要弄清楚新技术的正确使用场景和需要注意的地方。现 在,Docker很容易应用到开发环境。使用Docker可以很容易地搭建出很多不同的环境(至少,给人的感觉是能够搭建出不同的环境),这对于开发很有 用。

  而在生产环境中,Docker的不成熟和不完善也限制了使用场景。比如,Docker不直接支持对多机器的网络和资源的监控,这使得它几乎无法在生 产环境中使用。当然也有很多有潜力的地方,比如可以将同一个package从开发环境直接部署到生产环境。还有一些Docker运行时特性对于生产环境也 很有用。但是总的来说,在生产环境里,目前不足多于优势。这并不是说无法成功运用到生产环境,只是现在还不能指望它一下子成熟和完美。

  4. Docker是跨OS的

  另一个误解是Docker在任意操作系统和环境上都可以工作。这可能来自于装卸货物的集装箱的类比,但是软件和操作系统的关系可不像船位那么简单直接。

  实际上,Docker只是Linux上的技术。并且Docker依赖特定的内核特性,必须要有最新版本的内核才行。基于不同OS的差异性,跨OS 时,如果使用的不是最底层通用的特性,会遇到很多麻烦的问题。这些问题可能只有1%的发生率,但是当你在多台服务器上部署时,1%也是致命的。

  虽然Docker只在Linux上运行,但是也可以在OS X或者Windows上使用Docker。使用boot2docker会在OS X或Windows机器上运行一个Linux虚拟机,这样Docker可以在这个虚拟机里运行。

  5. Docker增强应用的安全性

  觉得Docker可以改进代码和交付代码过程的安全性,这也是误解。这也是真实的集装箱和软件上容器的差别。Docker是一种容器化技术,添加了 编排方法。但是Linux的容器有一些安全漏洞可能会被攻击。Docker并没有为这些漏洞添加任何安全层或者补丁。它还不是能保护应用的铁布衫。

  从Java角度看

  一些Java开发人员已经开始使用Docker。Docker的某些特性让我们更容易构建可扩展的上下文环境。不像uber-jar,Docker 可以帮助你将所有的依赖(包括JVM)打包到一个随时可发布的镜像中。这也是Docker对于开发人员来说最迷人的地方。但是,这也会带来一些隐患。一般 来说,程序员需要用不同的方式和代码交互 – 监控它,调试它,连接它,调优它….如果使用Docker,这些都会需要额外的工作。

  比如,我们想使用jconsole,它依赖于JMX功能,JMX因为要使用RMI又需要网络。使用Docker的话就不是很直接,需要一些技巧去开 启所需端口。我们最初发现这个问题是当我们想要构建Takipi的Docker应用,我们不得不在容器里JVM之外运行了一个后台程序。详细的解决方案在 GitHub上。

  另外一个很严重的问题是Docker容器的性能调优相当困难。当使用容器时,你不知道每个容器到底会分配多少内存。如果你有20个容器,内存会以你 不确定的方式分配给它们。如果你打算用参数-Xmx调优堆的大小,就很困难,因为对Docker容器内JVM的处理取决于能够自动得到该容器分配到的内存 大小。如果都不知道分配了多少内存,性能调优几乎不可能。

  结论

  Docker是很有意思的技术,有一些真实有效的使用场景。作为一个新兴技术,还需要大量时间来解决缺失的功能和已知的bug。但是,现在这个领域的确有很多的炒作。不过记住哦,炒作可不是成功~

       感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

时间: 2024-09-20 00:40:16

Java 使用Docker时经常遇到的五个问题_java的相关文章

使用Docker时需要关注的五项安全问题

通过阅读网上帖子以及浏览相关新闻,大家可能会产生一种先入为主的印象,即Docker天生安全性薄弱且尚不足以被直接引入生产环境.不过实际情况是,虽然我们需要对容器安全性加以高度关注,但只要使用得当,其完全可以成为一套远优于单独使用虚拟机或者裸机的安全.高效生产系统. 要安全地使用Docker方案,大家首先需要了解其面对的潜在安全问题,并掌握能够对基于容器之系统加以切实保护的各类主要工具与技术. 大家还需要随时牢记以下五个问题,并在利用Docker承载关键性任务应用程序的整个流程当中秉承这种谨慎的态

五个基于Java的Docker镜像

[原文编者的话]Java 语言长期占据编程语言前三甲的位置,其受欢迎程度与重要性不言而喻.在容器化技术大潮中,Java 可扬容器化之长,避自身"臃肿"之短,取得更高成就.本文选择了5个有代表性的 Java 镜像进行了介绍,并指出了其现存的一些问题和解决方案,供相关人员参考. 尽管 Java 看起来不是很"时髦",但仍是一门在移动市场.开源界及企业中占据主导地位的非常受欢迎的重要的语言.举个例子,你可知道在 Apache 软件基金会中63%的项目是用 Java 写的么

一个简单的Java EE&Docker示例

本文讲的是一个简单的Java EE&Docker示例,[编者的话]学习Docker的最好办法就是迅速在工作中应用它,本文作者使用Docker部署了一个Java EE应用,非常简单和方便.需要注意的是,由于作者写作时本地网络有问题,所以Dockerfile中很多的资源都没有从网络下载,你再实践时,可以尝试修改.学习快乐 :) 本文中,我们将会把Java EE和Docker结合,具体内容如下: 创建.构建并运行一个Docker镜像: 通过镜像启动一个Wildfly服务器,并部署了一个JavaEE示例

java创建socket时失败的原因有哪些?

问题描述 java创建socket时失败的原因有哪些? 最近练习使用socket时,本来能够脸上服务器的,后来不知道怎么的就连不上了,最后定位就是socket创建失败,什么原因我不知道.我知道的原因如下: 1.没有添加连接网络权限. 2.没有在后台线程中创建socket 3.端口号被占用 这些问题我都避免了,而且之前就连上了,后来连不上,抛出IOException,请问还有其他的原因会导致socket创建失败吗? 解决方案 抛出io异常,文件读取的问题.serversocket没有写进数据,so

阅读java项目源代码时的问题

问题描述 阅读java项目源代码时的问题 在阅读项目源代码的时候,会遇到很多方法,如何判断方法是系统自带的或者是开发者自己自定义编写的啊 解决方案 ctrl+左键如果是自带的是不能打开看源代码的,如果是自己写的就可以跳转到方法或变量的声明位置 解决方案二: 看是哪个对象的方法,然后接着看那个对象是哪个类的,在看那个类位于哪个包下,如果是Java源代码包下的类,就是系统自带的,而且你可以点击那个类查看,开发者自己定义的包和类应该看得出来. 解决方案三: 在变量上/方法上点右键,转到定义(goto

怎么在java项目运行时调试bug

问题描述 怎么在java项目运行时调试bug 如题,怎么在java项目运行时调试bug?这是一道面试题,感觉没思路啊. 解决方案 debug模式,log4j打印日志,单步运行打断点 解决方案二: 首先应该通过BUG的表现确定BUG可能产生的范围.如果是数据表现,那么应该关注数据操作部分的代码,简单的错误,通过代码复查应该能排除.如果是异常表现,那么看一下异常信息,获取错误代码行,如果有经验应该能直接排除.怎么看都觉得自己代码正确(貌似都这赶脚)...好吧,各种IDE工具都提供DEBUG功能,在预

java 游戏开发-Java 运行程序时,错误调用函数,

问题描述 Java 运行程序时,错误调用函数, 做的一个棋类小游戏,有条规则是棋子变成王后,可以远距离吃子,在编写王吃子规则时,需要使用if语句对是否是王进行判断,但是在运行时,还没有变成王,就输出判断为王时的提示语句,

JAVA编写日历时随便给一个号数怎么知道当天星期几,算法是怎么样的?

问题描述 JAVA编写日历时随便给一个号数怎么知道当天星期几,算法是怎么样的? 我初学正在写日历的代码,如图,我在写一个月最后添加下个月的开始几天,求随便给个号数怎么知道当天星期几?要算法 不要函数 解决方案 365 * --年 + (年 / 4 - 年 / 100 + 年 / 400) + 月 + 日 % 7 以上是计算公式 解决方案二: java的日历类,可以得到某个日期的年月日.星期等属性的.Calendar类有关于时间的各种属性的,年月日.时分秒.星期等. 参考:http://blog.

阿里云服务器安装DOCKER时出错

问题描述 阿里云服务器安装DOCKER时出错 我在阿里云服务器的配置是centos 7 64位 ,docker安装完成,但是无法启动,出现如下异常,请高手帮忙