在七月底,Spring Boot和Dropwizard分别发布了1.4和1.0版本,它们都是基于Fat JAR的。随着人们更多地采用这些框架和微服务架构,Fat JAR成为了通用的部署机制。
\\Fat JAR技术会将Java应用的所有依赖打包到一个bundle之中,便于执行,这种方式用到了很多的Java微服务框架之中,包括Spring Boot和Dropwizard,甚至还有一个专门的Fat JAR Eclipse插件。
\\对于具有少量微服务的组织来说,Fat JAR所占用的带宽可能并不那么明显。但是,如果你有上千个微服务的话,那么它们所使用的带宽就会成为一个问题了。
\\在今年夏天的早些时候,HubSpot曾经提到过借助maven-shade-plugin进行Fat JAR部署所遇到的问题,并介绍了他们将100,000个小文件打包到一个JAR中所遇到的性能问题。他们还提到,1,000个以上的应用进行持续不断地构建和部署,会产生大量重复的JAR依赖。
\\他们曾经尝试使用maven-dependency-plugin来减缓这种快速膨胀,但是他们的努力并没有减少所生成的构建工件(artifact)的大小。
\\为了解决Fat JAR所带来的痛苦,HubSpot创建了用于Maven的SlimFast插件,它所创建的构建工件只会包含指定项目的类。它会依附到部署阶段上,并将应用的所有依赖分别上传到Amazon Simple Storage Service(S3)之中。通过使用这个插件,HubSpot的报告显示,构建时间快了60%,并且可用的存储容量增加了99%。
\\下图展现了使用SlimFast之后,所带来的构建速度提升:
\\\\为了更深入地了解HubSpot所面临的Fat JAR问题,InfoQ采访了他们的软件工程师Jonathan Haber。
\\InfoQ:你们所遇到的Fat JAR问题大部分都是由持续集成和部署引起的吗?
\\\\\Jonathan Haber:是的,我认为我们所遇到的问题很大程度上都是由我们的开发风格所导致的。我们有很多小团队,他们都在推送代码、构建和部署,这样的活动每天都有上百次。因为我们的构建单元很小,所以创建和上传Fat JAR所消耗的时间有时比编译和测试代码的时间还长。话说回来,如果你采用单体结构的话,构建所需的时间可能会超过20分钟,那么相对来讲Fat JAR的消耗就没有那么明显。但是,我认为有更多的公司在转向这种更快、更轻量级的部署风格,因此可能会面临同样的挑战。
\
InfoQ:你认为像SlimFast这样的替代性打包技术是否应该作为框架的原生方案,比如添加到Spring Boot和Dropwizard中?
\\\\\Haber:因为这种方式需要与构建和部署系统集成,我的感觉是如果将其包含在Spring Boot或Dropwizard中的话,那就太带有倾向性了。但是,有一种处理方式就是将SlimFast插件放到一个Maven profile之中,通过环境变量来激活。通过这种方式,构建系统能够表明它支持这个特性,否则的话,依然将会采用Fat JAR的方式。
\
InfoQ:如果云提供商(如Heroku、CloudFoundry等)采用类似的技术来减少应用之间重复的JAR,那么他们在带宽方面是不是可以节省很多钱?
\\\\\Haber:我并不确定能够节省到什么程度,但是我认为采用类似的策略是可行的。不过,我们的优势在于所有的应用都使用了相同版本的第三方库,所使用的库有大量的重叠。对于云提供商来说,他们的用户所依赖的库会广泛得多,会跨所有的不同版本,所以如果你想在应用服务器上缓存依赖的话,会需要大量的空间。但是,如果你不这样的话,速度/带宽方面的大量节省就会不复存在。这并不是说,完全没有节省,我只是认为他们的实现会比我们的方式更加复杂。另外一个问题在于,这些云提供商通常只会基于用户的POM来运行Maven,所以他们对于构建生命周期并没有太多的控制权,无法添加这种类型的优化。
\
InfoQ:在Fat JAR应用方面,你希望看到有哪些改善呢?
\\\\\Haber:如果Java能够处理嵌套JAR的话,那么构建和运行Fat JAR都会容易很多,我并不确定这一点是否会包含在Java 9的功能列表中。像Spring Boot和One-JAR这样的工具都能很好地解决这种局限性,但是他们增加了复杂性并且无法做到完全的透明。
\
查看英文原文:Solving Fat JAR Woes at HubSpot