5月31日 23:47

Maven 构建速度慢该怎么优化?

Maven 构建慢,通常不是某一个开关没打开,而是依赖下载、测试执行、插件配置、多模块顺序和 CI 缓存一起拖慢了速度。优化时不要先急着跳过所有检查,先用 mvn -X、CI 日志或构建耗时统计看瓶颈在哪:是下载依赖慢、单元测试慢、编译慢,还是打包插件慢。真正稳妥的做法,是把“本地开发更快”和“流水线发布可靠”分开配置。

常用优化配置

本地开发可以优先使用并行构建和跳过非必要步骤:

bash
mvn clean install -T 1C mvn test -pl user-service -am mvn package -DskipTests

-T 1C 表示按 CPU 核心数并行构建,适合多模块项目;-pl 指定模块,-am 自动构建它依赖的上游模块。CI 中更推荐缓存本地仓库,并固定 Maven、JDK 和插件版本,避免每次构建都重新解析依赖。

xml
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.2.5</version> <configuration> <reuseForks>true</reuseForks> <forkCount>1C</forkCount> </configuration> </plugin>

测试很慢时,不要只知道 -DskipTests。它会编译测试但不执行;-Dmaven.test.skip=true 连测试编译也跳过,速度更快,但更容易把测试代码编译错误带到后面才暴露。

追问

Maven 并行构建一定会更快吗?

不一定。多模块项目之间如果依赖链很长,Maven 仍然要按依赖顺序执行,能并行的部分有限。并行构建还会放大线程安全问题,一些老插件或自定义插件没有标注 thread-safe,可能出现偶发失败。取舍上,本地开发可以大胆用 -T 1C,发布流水线则要先跑几轮稳定性验证,再决定是否启用。

-DskipTests-Dmaven.test.skip=true 怎么选?

-DskipTests 只跳过测试执行,测试源码仍会编译,因此能发现测试代码里的编译错误。-Dmaven.test.skip=true 会跳过测试编译和执行,适合临时打包或验证非测试相关改动。坑在于它可能掩盖测试代码与主代码 API 不兼容的问题,等到合并或发布阶段才炸。团队里一般把前者用于普通开发,后者限制在明确知道风险的临时场景。

多模块项目只构建一个模块会不会漏东西?

如果只写 -pl order-service,Maven 只构建这个模块,依赖的本地模块可能不会自动更新。通常要配合 -am,让 Maven 把它依赖的上游模块一起构建。反过来,-amd 会构建依赖当前模块的下游模块,更适合底层公共模块改动后的影响面验证。边界是模块关系必须在 reactor 里可见,跨仓库依赖仍然需要先安装或发布到仓库。

CI 里优化 Maven 构建最值得做什么?

最先做缓存,而不是先砍测试。缓存 ~/.m2/repository 能减少大量依赖下载时间,尤其是依赖多、网络不稳定的流水线。其次固定插件版本,否则 Maven 可能解析到不同插件版本,构建时间和结果都不稳定。需要注意的是,缓存也可能带来脏依赖问题,遇到无法解释的构建错误时要支持手动清缓存重跑。

Maven 编译插件有哪些容易忽略的配置?

最常见的是没有固定 maven-compiler-plugin 版本和 Java release,导致本地和 CI 使用不同 JDK 时行为不一致。推荐用 release 而不是只写 sourcetarget,它能同时限制可用 API。示例配置如下:

xml
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.13.0</version> <configuration> <release>17</release> </configuration> </plugin>

速度优化最终要服务于稳定交付。开发机上可以用并行、局部构建和跳过测试节省时间;主干和发布流水线则要保留必要校验,只把依赖缓存、插件固定和模块拆分做到位。

标签:Maven