编者按: 本文作者Ron Pressler是Parallel Universe公司的创始人,拥有着丰富的高性能开发经验。通过这篇文章,Ron向大家详细介绍了全新的开源JVM部署工具——Capsule。
以下为译文:
现实世界中,应用程序部署过程可能没有想象中的那么简单。应用程序其实非常“敏感”,在部署过程中,它会发现自己身处一个陌生的环境中,并且在与不同硬件、不同基础设施软件,以及陌生的邻居(应用程序)行交互。如果期望应用程序正常地运行,编码和部署过程都是重中之重。两者之间的平衡常常依赖于程序的编写语言、程序构成的运行时和工具,因此,不同的技术栈可能需要不同的部署工具。
但JVM应用程序对环境的要求非常少——只需一个JVM和一个内核,然而意想不到是, 目前为止尚不存在一个通用的JVM应用部署工具/机制。Fat JARs并不总奏效,而且它们需要平台特定的脚本。最近有人使用Docker来部署Java应用,事实上Docker并不适用于这种任务:它的主要目的之一是提供通用的应用可移植性(类似JVM应用已经具备的特性),同时它也需要下载、部署并管理各种full-OS镜像和存repositories。作为运行时不可知工具,Docker也无法利用JVMs 的优势。
当下,经过一年的发展,Capsule 1.0正式发布——一个简单、健壮且灵活的JVM应用部署工具。Capsule迎合JVM应用的独特优势和需求,因此这里有理由相信这是最简单、最强大的JVM应用部署方式,不管是用于一个桌面应用、microservice或复杂的Web应用。Capsule不仅适用于Java应用程序,还能应用于所有JVM语言,从Jruby、Jython和Groovy,到Kotlin、Clojure和Scala,再到Frege和OCaml-Java。如果你在写JVM程序,给Capsule一个机会。
你可以这样来理解capsule,将它当作steroids上的1个fat JAR(在允许本地库的同时也不会干扰到依赖项)与1个声明式启动脚本的整合;另一个理解方式是,将其当作部署阶段的构建工具。正如构建管理工具一样, Capsule从构建到应用发布的各个环节都有全方位的管理。
Capsule在设计时一直遵循以下原则:
Capsule Magic with Caplets
通过Caplets实现的Capsule魔法
Capsule之所以能保持简单还能提供这些功能主要归功于caplets,以模块化定制Capsule行为。Caplets可以嵌入到1个capsule,或者单独进行包装并使用命令行包装和修改现有capsule行为。
Capsule的第一个caplet是Maven caplet,允许开发者在manifest attributes中声明部分或全部的应用依赖关系,而不用嵌入到capsule JAR里。虽然这对许多应用来说并不必要,不妨通过以下两个用例来深入了解Capsule的潜力。
首先是一个简单的Hello World servlet。建成后,它将创建一个标准的WAR文件并部署到任何servlet容器。仔细观察后发现,WAR的确有点特别。其内容是:
247 META-INF/MANIFEST.MF 1124 WEB-INF/classes/co/paralleluniverse/examples/HelloWorldServlet.class 653 WEB-INF/web.xml 161596 Capsule.class 1467463 capsule-maven-1.0.jar
如你所见, WAR包含Capsule 类,这意味着它是一个capsule,也是嵌入式JAR,而 capsule-maven-1.0.jar是Maven caplet。JAR manifest是这样的:
Manifest-Version: 1.0 Main-Class: Capsule Premain-Class: Capsule Caplets: co.paralleluniverse:capsule-maven:1.0 Application: org.eclipse.jetty:jetty-runner:9.3.3.v20150827 Allow-Snapshots: true Min-Java-Version: 1.7.0 Args: $CAPSULE_JAR
取代部署WAR到servlet容器,你可以直接执行 java -jar build/libs/capsule-runnable-war.war (或者,甚至简单的./capsule-runnable-war.war,如果capsule是“真正可执行”——见用户文档的指令),它会自动下载Jetty,并用Jetty来启动servlet。Jetty工件将被缓存,并可以共享到其他需要的caplets中。
608 META-INF/MANIFEST.MF 161596 Capsule.class 1467463 capsule-maven-1.0.jar 266 app.js
当capsule发布,Avatar运行时——包括针对本地操作系统的本地库,将从Maven repository下载到本地并缓存,并与其他Avatar capsules共享。
其他caplets将包含:一个守护进程caplet, 作为Unix或Windows守护进程来发布capsule;一个安全caplet,会在Java沙箱(通过安全策略定义)内启动capsule;一个desktop caplet,会将包含了一个GUI应用程序的capsule转化为一个Windows、Mac或Linux的本地可执行程序;一个容器caplet,在一个或多个容器内运行capsule。
为Capsules设计的轻量级容器
容器对沙箱应用来说是一个有效方式,可以简化部署和巩固服务器,所以对任何的软件堆栈而言,它们都非常有利于dev-ops和安全。然而,由于JVM应用只有最小的环境需求 (即一个内核和一个JVM),它们通常是可移植的,使用一个像Docker的容器解决方案无疑是浪费时间和空间。另一方面,shield caplet创建了一个轻量级容器,无需创建大图像。
例如,可以通过简单地桥接网络在1个容器中方便地运行quasar-stocks Web应用。
java -jar capsule-shield-0.1.0.jar quasar-stocks-thin.jar
随后就可以轻松地检索程序所运行的容器IP地址:
lxc-attach -P ~/.capsule/apps/quasarstocks.Application_0.1.0-SNAPSHOT/capsule-shield/ -n lxc -- /sbin/ifconfig
当一切如预期那样正常工作,无需任何复杂的操作,就可以在最终部署的服务器上(可能是一个守护进程)发布相同的命令来配置端口转发使服务公共可用,并通过沙箱保证了应用程序的强安全性。
Go with Capsule
是时间打开capsule.io并启动capsules了!
原文链接: Open Source JVM Application Deployment Tool: Capsule (译者/ OneAPM 工程师)