本文解决方案十分适配 M1 相关机型,X86 机型也有相关解决方案,博主这里实验机型为 Mac-mini M1。
目录
1.x86 + NoMirror + 单线程 Package
2.ARM + Aliyun Mirror + -T 1C Package
一.引言
对于一个 Java 算法大数据开发而言,每天最常做的事情就是 mvn package 打 jar 包,对于一些较大的项目,打一次包需要 5min 甚至更久,非常的不奈斯:
下面尝试优化 mvn package 速度,优化之前,首先看看哪些点可能影响我们的打包速度:
- jdk:Java 项目基于 JVM 编译
- 配置:即 CPU 的快慢
- 网速:maven 下载所需
基于上述几点,我们开始 mvn package 的优化。
二.JDK 的选择
这里主要适用于 M1 芯片下的 ARM 架构,传统 x86 只能使用下述的其他优化方案。
1.更换 JDK x ARM
M1 芯片的引入大大提高了 mac 的工作效率,为此 jdk 也针对 M1 推出了专用的 jdk 版本,大家可以通过 IDEA 直接下载对应版本即可,例如你使用 JDK-1.8,则在下载时选择 JDK-1.8-ARM 版本即可,一般 ARM 框架的都包含 aarch 标识,通过 File -> Project Structure -> SDKs 打开:
下载后替换将其他 JDK 版本通过 "-" 号去除即可。
2.更换 Java 环境
上述通过 IDEA 实现了 JDK x ARM 的下载,但是只是把 JDK 应用于 IDEA 的使用,而 mvn package 是通过 Terminal,所以还需要我们在环境变量中再次配置。
A.获取本机的 JVM 虚拟环境版本
/usr/libexec/java_home -V
我们上面下载的 Java 版本为 Amazon,所以其对应版本就是 corretto-1.8.0_352。
B.更新至环境变量
打开 ~/.bashrc 或者 ~/.bash_profile,取上面版本的数字部分即 1.8.0_352 并添加至 bash 中:
#java8
alias java8='export JAVA_HOME=$(/usr/libexec/java_home -v 1.8.0_352)'
最后记得使用下述命令更新配置
source ~/.bashrc
source ~/.bash_profile
C.使用新环境变量
只需在 Terminal 输入 java8 即可:
java8
echo $JAVA_HOME 看一下,如果为上面 bash 中输入的版本即代表 Terminal JDK 更新完成:
/Users/XXX/Library/Java/JavaVirtualMachines/corretto-1.8.0_352/Contents/Home
三.网速优化
这里物理网速肯定是固定的,我们无法优化,不过我们可以通过配置 maven 镜像,提高 maven 下载相关依赖的速度,常见的镜像有 Aliyun。
1.打开 Maven Setting
通过 Idea 打开 maven settings.xml:
2.配置 Mirror
添加 <mirrors> 并在其中添加 aliyun mirror:
<mirrors>
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
</mirrors>
添加后相关下载均来自 aliyun,避免从公网下载网络不通畅导致打包速度延长:
Tips:
这里还有一些小伙伴有疑问,如果我配置多个镜像或者我已经有其他镜像怎么办。这里 mirrors 支持配置多个 mirror 镜像,但是实际使用中只能使用 1 个镜像,默认情况下使用第一个 mirror。理想情况下是镜像 A 没有的依赖去镜像 B 中寻找,但是实际是只有当镜像 A 无法连接时,才会到连接到镜像 B,所以大家需要根据自己的需求将项目需要的镜像放置到第一位或者使用时指定镜像 name,如果有公司的镜像,也可以以公司镜像为主。
四.多线程打包
maven 支持多线程打包,只需使用 -T 参数指定即可。
1.指定 CPU Cores
mvn -T $CoreNum package
2.指定 CPU 线程倍数
1C 代表使用 1倍的 CPU 线程数进行并行打包,也可以 2C、3C,一般而言 1C 即可。
mvn -T 1C package
Tips:
常规单体项目使用 -T 参数多线程打包效率有提升,但是提升效果有限,如果是多项目融合打包,使用 -T 参数效果明显。
五.更多尝试
1.项目精简
由于编译期间需要将多个 java 文件编译为 .class,所以项目内的代码数量与文件数量一会影响 mvn package 的效率,如果项目里有多余的文件或者代码,可以进行代码瘦身,提高编译效率。
2.忽略测试
忽略编译中的测试阶段:
mvn package -DskipTests
如果本身没有指定测试类即可忽略,maven 打包期间也会自动提示:
3.本地运行预编译
如果可以在运行前先在本地运行一下待编译项目,也可以大大提高 mvn package 效率,因为本机运行项目时需要先对项目编译一次,从而后面 package 时的编译时间即可节省,当然本质上都一样,就是至少得编译一次。
mvn clean 后 package:
run 后 package:
可以看到差距还是很大的。
六.Mvn Package 实战检验
- 更换 JDK 版本为 ARM 系列
- 更换 Aliyun Mirror
- 采用多线程 -T 1C 打包
本次优化主要修改上述三个部分,下面看一下实战效果。
1.x86 + NoMirror + 单线程 Package
mvn clean 后打包:
run 后打包:
分别耗时 3:42 min 与 23.454 s。
2.ARM + Aliyun Mirror + -T 1C Package
mvn clean 后打包:
run 后打包:
分别耗时 1:27 min 和 13.533s,优化效果明显。
Tips:
这里两个打包界面不同是因为 Bash 中配置了新的 Java 虚拟机,所以为了测试老版本打包切换为了 Zsh,如果需要切换 shell 可以使用如下命令:
chsh -s /bin/bash
七.总结
mvn package 的效率优化大致这么多,clean 状态下 3:42 min 优化至 1:27 min,效率提升了 62% +,run 状态下 23.452s 优化至 13.533s,效率提升了 42%,非常的奈斯 👍 除此之外,之前还出过一期 Spark 项目提交优化的方法,Spark-Submit 时间过长的同学也可以参考:Spark On Yarn --jars/spark.yarn.jars 踩坑 与 提升spark submit速度。