Gradle构建慢是很多团队的通病,尤其当项目模块数量超过二十个、依赖关系复杂之后,一次全量构建可能要跑十几分钟。其实构建慢的很大一部分原因在于重复劳动:同一个commit,CI机器编译过一次,每个开发者的本地机器又各自编译一次,产物完全相同却浪费了大量CPU时间。Remote Build Cache就是为了解决这个问题而生的机制,它把任务执行后的输出产物存到一个共享的缓存服务器上,任何人在构建时只要任务输入没有变化,就可以直接下载缓存产物而跳过实际执行。

Remote Build Cache的工作原理
Gradle的缓存体系分为本地缓存和远程缓存两层。本地构建缓存默认存放在用户目录下的.gradle/caches/build-cache-1目录,远程构建缓存则是一个HTTP服务,Gradle会以RESTful的方式与它交互:上传时向服务器PUT一个以缓存键命名的压缩包,拉取时先尝试HEAD请求探测缓存是否存在,存在则GET下载并解压到任务输出目录。
缓存键的生成是整个机制的核心。Gradle会对任务的输入进行哈希计算,包括输入文件的完整内容、任务类型、classpath、注解处理器输出等所有影响输出的因素。任何一个字节发生变化,哈希值就不同,缓存自然不会命中。这个设计保证了缓存的正确性:相同的输入必然产生相同的键,理论上也就能复用相同的输出。
值得注意的是,任务输出必须具有确定性才能真正享受缓存收益。如果任务输出里包含时间戳、随机数、绝对路径等不稳定因素,即使输入相同,每次产物也不一样,这类任务要么不适合缓存,要么需要改造。可以运行gradle --scan查看构建报告,其中会明确标注每个任务是否可缓存以及缓存命中的情况。
如何在项目中配置远程缓存
配置远程缓存推荐放在settings.gradle中,这样对所有项目和所有任务统一生效。最基本的配置如下:
buildCache {
local {
// 本地缓存默认开启,可设置存放目录
directory = new File(rootDir, 'build-cache')
removeUnusedEntriesAfterDays = 30
}
remote(HttpBuildCache) {
// 缓存服务器地址
url = 'http://cache.internal.ipipp.com/cache/'
// 是否允许上传缓存(CI开启,本地一般只拉取)
push = true
}
}这里有一个实践上的关键点:push权限应该只在CI机器上开启。原因是CI环境干净可控,构建结果可信;开发者的本地环境千差万别,可能出现修改过的JDK或者本地补丁,如果把这类产物推送到共享缓存,会污染整个团队的构建结果。可以通过环境变量来区分:
remote(HttpBuildCache) {
url = System.getenv('GRADLE_CACHE_URL') ?: 'http://cache.internal.ipipp.com/cache/'
push = System.getenv('CI') != null
}除了配置缓存服务器,还得保证任务本身支持缓存。Gradle内置的编译、打包任务大多已经标注了@CacheableTask,自定义任务则需要显式添加注解并声明输入输出:
@CacheableTask
abstract class MyTask extends DefaultTask {
@InputFile
abstract RegularFileProperty getConfigFile()
@OutputDirectory
abstract DirectoryProperty getOutputDir()
@TaskAction
void run() {
// 读取输入文件,生成输出到outputDir
}
}自建缓存服务器与常见坑点
官方推荐使用Gradle Build Cache Node这种商业方案,但对大多数团队来说,一个支持PUT方法的Nginx或者S3兼容存储就够用了。用Docker跑一个Nginx,配置WebDAV模块开启PUT权限,就是最简单的缓存服务器。需要注意的是缓存键就是文件名,服务端不需要理解内容,只需要原样存储和返回即可。
落地过程中最容易踩的坑有三个。第一个是路径差异:Windows和Linux的路径分隔符不同,一些硬编码绝对路径的构建脚本会导致跨平台缓存永不命中,解决办法是把所有路径统一交给Gradle的API管理。第二个是增量构建与缓存的混淆:UP-TO-DATE表示本地增量检查通过,FROM-CACHE才表示命中了构建缓存,排查时要区分清楚。第三个是缓存击穿:当某个基础模块频繁改动时,依赖它的下游模块缓存会连锁失效,这时应该合理拆分模块,让稳定的代码和频繁变动的代码解耦。
最后建议在CI流水线中采用先拉取后推送的策略:每次构建开始时从远程缓存拉取,构建结束后把新产物推送上去,这样后续的开发者和下一轮CI都能直接受益。落地之后建议持续观察--scan报告中的缓存命中率,一般成熟项目的编译任务命中率能稳定在70%以上,全量构建时间可以从十几分钟压缩到两三分钟,收益非常可观。
GradleRemote Build Cache构建加速修改时间:2026-09-04 15:48:35