写点什么

在 HubSpot 是如何应对 Fat JAR 困境的

  • 2016-08-28
  • 本文字数:1609 字

    阅读完需:约 5 分钟

在七月底,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

2016-08-28 19:002307

评论

发布
暂无评论
发现更多内容

我认为“写作平台”还缺少读者

小天同学

产品 反馈 写作平台 建议

五、Docker 数据持久化存储与性能调优

悟尘

Docker 容器 k8s Compose kubernet

H5功能足够强大,为什么还要微信小程序?

顾强

微信小程序 移动应用

Hexo-admonition 插件安装使用指南

悟尘

Hexo Hexo-admonition Admonition

废掉一个人最好的办法是让他忙到没有时间思考

熊斌

程序员 职场 思考

写在开头

杨友峰

Java 期现

长假将至,推荐两个好东西

池建强

算法 视觉笔记

Netty 源码解析(二):Netty 的 Channel

猿灯塔

Netty

三、基于 Docker-registry/Nexus3 搭建本地仓库

悟尘

Docker Kubernetes 容器 k8s Compose

告诉你一个学习编程的诀窍(建议收藏)

ithuangqing

学习 编程 自学编程

意想不到的收获哦

南辞

源码分析 Vector 和 ArrayList

张sir

Java 源码 collection

使用Typora + PicGo 图床 + jsDelivr CDN实现高效 Markdown 创作

悟尘

Typora PicGo iPic jsDelivr CDN

二、基于 Dockerfile 构建并运行镜像

悟尘

Docker Kubernetes 容器 k8s Compose

附录4、Docker-compose 配置文件编写指南

悟尘

Docker Docker-compose

Hexo-deployer-cos-cdn 插件安装使用指南

悟尘

Hexo COS CDN Hexo-deployer-cos-cdn

六、基于多阶段构建减小镜像体积降低复杂度

悟尘

Docker Kubernetes 容器 k8s Compose

四、Docker 网络原理、分类及容器互联配置

悟尘

Docker Kubernetes 容器 k8s Compose

七、Docker Compose 入门实践

悟尘

Docker Kubernetes 容器 k8s Compose

附录2、Dockerfile 参考及最佳实践

悟尘

Docker Dockerfile

Node.js 必知必会(安装配置、应用实例及同步控制)

悟尘

node.js

游戏夜读 | 设计师的数据模型

game1night

Netty 源码解析(三): Netty 的 Future 和 Promise

猿灯塔

web集群架构

桥哥技术之路

为什么说此前的WiFi安全方案都是小弟?

石君

wifi 无线网络 无线网络安全 Wi-Fi安全

附录1、Docker 常用命令及示例

悟尘

Docker 容器

八、Kubernetes 入门实践

悟尘

Docker Kubernetes 容器 k8s Compose

附录3、Docker-compose 命令使用指南

悟尘

Docker Docker-compose

VSCode-aliyun-oss-paste-image 插件安装使用指南

悟尘

vscode Paste-image

Redis高可用-哨兵模式配置

Geek_0o5u34

redis 高可用 主从配置 redis高可用 redis哨兵模式

一、Docker基础入门及架构介绍

悟尘

Docker Kubernetes 容器 k8s Compose

在HubSpot是如何应对Fat JAR困境的_Java_Matt Raible_InfoQ精选文章