与其他更接近Unix二进制语言的语言相比,使用Java时使用Docker的开发优势是否被否定?


53

我有一个朋友说:

Docker很棒。您可以使用它在本地计算机上复制生产及其所有怪癖。然后,您可以超快速地通过所有登台工作流直接部署该实例。

现在,如果开发人员正在编写Ruby,PHP或Go(存在指向操作系统的定向二进制链接),这将是正确的。

但是当使用Java时 - 操作系统和语言之间已经存在一个虚拟层,无论底层操作系统如何,都可以确保操作的一致性。

可以说,在这种情况下,否定了为本地开发人员运行Docker来复制生产环境的好处。(与Ruby,PHP或Go相比)。

我愿意就此进行讨论,并热切希望听到持异议的观点(有证据)。

与其他更接近Unix二进制语言的语言相比,使用Java时使用Docker的开发优势是否被否定?


34
为什么您认为ruby和php是二进制文件?从技术上讲,Ruby和php比Java更虚拟-在Java中,您必须先编译然后在虚拟机中执行程序。在Ruby和php中,您附带了源代码,虚拟机直接读取了源代码。
slebetman

12
“但是当使用Java时-操作系统和语言之间已经存在一个虚拟层,无论底层操作系统如何,都可以确保操作的一致性。” LOL。Java发明了“编写一次,到处测试”。
安迪

2
Java是一个不断发展的目标。有时会引入一些破坏性功能(几年前加强安全性就是最好的例子),或者您遇到需要使用特定版本的错误。与使用主机的本机打包系统相比,在Docker中控制此命令要容易得多。
托尔比约恩Ravn的安徒生

1
“不管底层操作系统如何,都使操作保持一致”请注意,使语言运行时行为始终如一,并不否认您可能仍然具有一些外部依赖关系这一事实。就像将特定文件路径用于日志一样简单。
jpmc26

Answers:


86

一点也不。

假设您在开发计算机和服务器上都在运行Java 1.8.0版。顺便说一下,您正在同时使用Java开发两个项目。

一天,在JVM中发现一个错误,并且将运行您正在处理的第一个项目的服务器迁移到1.8.1。顺便说一句,运行第二个项目的服务器不受该错误的影响,并由不同的系统管理员团队管理,他们可能不愿意更新到1.8.1。

现在,至少对于其中一个项目,您正在运行其他版本的Java。

这可能不会给您带来太多麻烦(直到一台服务器迁移到1.9,而另一台则保留旧版本),但这意味着您不再在本地计算机上复制生产环境,这使得微型服务器成为可能。爬虫。

如果您认为文件系统,依赖项,安全设置,本地配置以及Linux本身的版本与生产环境有所不同,则您可能会面临编写将在生产环境中失败的代码的风险。不用冒险,您可以使用虚拟化或Docker,而不会造成很小的生产力损失。


20
在大公司中,这种事情一直都在发生。这不仅仅是理论上的事情。
enderland '17

5
发现Docker中的错误时该怎么办?
Owen

Java 9也会破坏事情。需要付出一些努力。
托尔比约恩Ravn的安徒生

8
@Owen当您发现Java中的错误时,您会做同样的事情。或在{Linux,Windows}中。或在您的CPU中
Kroltan

1
@Trilarion:是的,尽管主要是公司开发人员的博客文章形式。也就是说,docker.com / customers上的任何“了解更多”链接将提供大型公司使用docker解决此类问题的示例。就是说,通常这些公司认为他们需要生产和开发之间的完美匹配,并通过VM来实现这一点是理所当然的。后来,他们意识到,“嘿,Docker解决了与VM相同的问题,除了它运行速度更快并且可用于保持部署一致之外。”
布赖恩

35

您很少只部署“ Java应用程序”。您的Java应用程序周围有很多不同的支持程序。我们使用Apache HTTPD,Apache Tomcat,ActiveMQ进行消息传递,FTP Deamon,MySQL和一些自定义服务来与不能直接与Java一起工作的程序集成。

甚至没有附带它的开发软件-eclipse,ant,adobe flex,groovy,firefox和subversion(我跳过了很多)

设置新工作站需要一整天到一周的时间-我们已经讨论了迁移到Docker可以简化此问题。如果我们能够在几个小时内可靠地推出新工作站,那将是惊人的。

更不用说我们部署时需要维护多达-20台服务器的事实。Docker开始看起来很划算!

(对于一次只在单个服务器上运行的应用程序,20似乎很痛苦……但是将一个服务器乘以clusters(x2),test / staging / prod(x3),Internal / External(x2)和主站点/ backup site(x2),您很快就会站起来)


为什么不制作图像?
德米特里·库德里亚夫采夫

我们希望如此。我们是一个很小的团队,试图将功能添加到一个使用率很高/重要的系统中,并且对服务器没有足够的控制权来决定其部署。虽然可能将其用于开发人员,但我们已经在32mb内存上受到了很大的限制-我认为从docker映像运行会产生一些开销...但是我们的计划是朝这个方向发展。
Bill K

我的意思是工作站
Dmitry Kudriavtsev

时间和内存-我们已经不得不放弃工作才能在我们的32GB工作站中运行(64GB服务器可以正常运行)。不过,我们已经进行了一些试验,下次需要构建新的开发人员工作站时可以尝试一下。
Bill K

8

这个问题也与golang有关,在其中您可以提取静态链接的二进制文件并在某个地方运行它们,而Python或C ++则通常具有大量的链接库,这导致人们只需要在其中构建一个docker容器即可。开发环境。

这里有两点要回答:

一:必须有更好的方法,而有:您可以仅使用安装环境来构建较小(且效率更高)的Docker容器,这带来了与Golang-with-environment和Golang-just相比的类似优势-binaries容器。对于Java,可以构建一个胖jar或包含所有库jar和一个shell脚本的可安装应用程序。就Python而言,您可以使用auditwheel来构建独立于构建环境的独立轮子(也可以使用带有静态链接的C ++来达到几乎相同的效果)。

第二:您需要docker做什么?在Java领域中,您可以使用类加载器在不同组件之间进行很多分离,但是要点是Java应用程序的本质。没有Java应用程序会自己运行-如果它不在docker中运行,则通常必须由supervisor或systemd等进行监督。输入Kubernetes,Marathon或Docker云,它们使用容器抽象来虚拟化主机本身,而不是虚拟化整个网络,这样您就可以部署容器并且它们可以在某些随机主机上运行。

微服务通常在基于docker的云上运行,因为它使您可以将docker主机视为牛,而不是宠物,并且类似于docker化的应用程序。当然,一旦将主机卷安装到docker上,并且需要在具有这些卷的主机上准确运行docker容器,这种抽象就会泄漏。有些人甚至可以绕开它。


5

这是一个非常好的问题,但是在使用Docker之后,我会解决这个问题:

容器化(例如Docker)否定了JVM的优势吗?

容器确实挑战了很多我根据经验得出的关于开发的假设。例如,如果有人要在应用程序中对资源文件的路径进行硬编码,那么许多有经验的开发人员就会知道这是有问题的,因此您应该使其可配置。但是,如果您以容器为目标,真的是这样吗?构建容器时,您告诉它目录结构是什么。您正在那里配置路径。那么您应该配置两次吗?有什么好处?如果您不匹配它们,它将无法正常工作……干吗?

我最近使用Java和Docker创建了一个原型应用程序,该应用程序实际上监视了GC事件,当堆的旧部分达到阈值百分比时,它将自行关闭。然后,Docker(群发模式)将启动一个新的。从本质上讲,它消除了对JVM中主要GC周期的需求,并让docker管理它们。它没有达到我期望的效果(客户端看到了关机的影响),但它的功能足以向人群进行现场演示。

如果您好奇的话,您真的应该尝试使用容器。它确实是一种破坏性技术,您需要掌握它。Docker是一个很好的起点,但是至少还有一个可行的替代方案,对所有人都有利,IMO。


“ ...但是至少还有另一种可行的替代方案对每个人都有好处”那么,另一种可行的替代方案又是哪一种呢?
Trilarion '17

@Trilarion rkt(或火箭)。Kubernetes和Docker目前都支持它。
JimmyJames
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.