第4章 远程缓存配置与集成:HTTP远程缓存、使用Redis/Artifactory作为后端、认证配置、安全传输
4.1 远程缓存的角色与架构
远程缓存是 Gradle 构建缓存体系的关键扩展,允许团队共享构建产物,避免重复编译。其核心架构如下:
建议:远程缓存最适合持续集成(CI)环境。团队内所有人共享同一套缓存,首次构建后后续流水线节省 50%~80% 的编译时间。
4.2 HTTP 远程缓存配置
Gradle 原生支持通过 HTTP/HTTPS 缓存后端。在 gradle.properties 或 settings.gradle 中配置一个可以 PUT/GET 资源的 HTTP 服务器:
# gradle.properties
org.gradle.caching=true
org.gradle.caching.http.url=https://cache.example.com/gradle-build-cache/
或者在 settings.gradle 中以构建脚本方式声明:
// settings.gradle
buildCache {
remote(HttpBuildCache) {
url = 'https://cache.example.com/gradle-build-cache/'
isPush = true
}
}
4.3 使用 Artifactory 作为后端
JFrog Artifactory 是企业级缓存后端,集成了通用制品仓库与构建缓存。配置步骤:
- 在 Artifactory 创建 通用仓库(Generic Repository)作为缓存目录。
- 启用 Artifactory 的
X-Gradle-Cache-Key头支持(部分版本需额外插件)。 - 在
settings.gradle指定密码或 API :
// settings.gradle
buildCache {
remote(HttpBuildCache) {
url = 'https://artifactory.example.com/artifactory/gradle-cache/'
isPush = true
credentials {
username = 'gradle-ci'
password = System.getenv('ARTIFACTORY_') ?: ''
}
}
}
注意:切勿将密码硬编码在版本控制中。使用环境变量或 Gradle 凭据提供者(Credentials Provider)传参。
4.4 使用 Redis 作为后端
Redis 不适合直接存放上百 MB 的构建产物,但是通过 Gradle Build Cache Node(第三方项目)可以桥接。典型部署如下:
| 组件 | 角色 | 配置参数 |
|---|---|---|
| Redis 集群 | 元数据与小文件存储 | redis://host:6379?timeout=10s |
| 对象存储 (S3/MinIO) | 大文件存储 | 桶名称、区域、访问密钥 |
| Build Cache Node | HTTP 代理 + 分层缓存 | 端口 5071,--backend redis |
| Gradle 端 | 指向 Node | http://cache-node:5071/cache/ |
运行缓存节点示例(Docker):
docker run -d --name gradle-cache-node \
-p 5071:5071 \
-e REDIS_URL=redis://redis-server:6379 \
-e S3_ENDPOINT=https://minio.example.com \
-e S3_BUCKET=gradle-cache \
-e S3_ACCESS_KEY=XXXX \
-e S3_SECRET_KEY=YYYY \
gradle/gradle-cache-node:3.0
4.5 认证配置方式对比
| 认证方式 | 适用场景 | 配置示例 | 安全级别 |
|---|---|---|---|
| HTTP Basic Auth | 自建 HTTP 缓存 | credentials { username '...'; password '...' } | 中(需配合 HTTPS) |
| API (Header) | Artifactory / Nexus | header 'X-JFrog-Art-Api', '...' | 高 |
| Bearer | OAuth2 认证 | header 'Authorization', 'Bearer ...' | 高 |
| mTLS (双向 TLS) | 企业最高安全 | JVM 系统属性 -Djavax.net.ssl.keyStore | 极高 |
自定义 Header 认证示例:
// settings.gradle
buildCache {
remote(HttpBuildCache) {
url = 'https://cache.internal.io/v1/'
header('X-Cache-', System.getenv('CACHE_'))
header('X-Project-ID', 'gradle-workspace')
}
}
4.6 安全传输与 TLS 配置
传输安全必须优先于功能实现。Gradle 使用 JVM 的信任存储验证 HTTPS 证书。常见配置:
- 使用受信任的 CA 签发证书(推荐生产环境)。
- 自签名证书 时,需要将证书导入 Java 信任库:
keytool -import -trustcacerts -file cache-cert.pem -keystore $JAVA_HOME/lib/security/cacerts -alias gradle-cache - 禁用证书验证(仅开发环境,不推荐):
// gradle.properties org.gradle.caching.http.url=https://cache.local:8443/ # 忽略证书错误 org.gradle.internal.http.connectionTimeout=30000 org.gradle.internal.http.socketTimeout=60000
最佳实践:在 CI 环境中使用环境变量
GRADLE_OPTS 添加信任库路径,而不是修改全局 cacerts:export GRADLE_OPTS="-Djavax.net.ssl.trustStore=/etc/gradle/truststore.jks"
4.7 调试与验证命令
配置完成后,使用以下命令验证远程缓存是否正常工作:
# 查看构建缓存配置生效情况
gradle --build-cache --info clean compileJava
# 检查远程缓存命中/未命中
gradle --build-cache --info --offline tasks
# 日志中应出现:
# Remote cache store for ... enabled
# Cache entry ... stored to http://...
# 使用 Gradle 的缓存诊断任务(需插件)
gradle buildCacheCheck --stacktrace
常见缓存未命中的原因日志示例:
# 认证失败
> Could not store build cache entry at https://cache.example.com/cache/... (401 Unauthorized)
# SSL 握手失败
> javax.net.ssl.SSLHandshakeException: PKIX path building failed
# 超时
> java.net.SocketTimeoutException: Read timed out
4.8 性能优化参数
| 参数 | 作用 | 推荐值 |
|---|---|---|
org.gradle.caching.http.connectionTimeout | HTTP 连接超时 | 10000(毫秒) |
org.gradle.caching.http.socketTimeout | 读取超时 | 120000 |
org.gradle.caching.http.maxSimultaneousConnections | 并发连接数 | 8~16 |
isPush | 是否允许上传缓存 | CI 环境为 true;开发者本地可为 false |
org.gradle.caching.local.cacheInitialSize | 本地缓存初始大小 | 500MB |
完整的高并发 settings.gradle 示例:
// settings.gradle
buildCache {
local {
directory = new File(System.getProperty('user.home'), '.gradle-cache')
removeUnusedEntriesAfterDays = 7
cacheInitialSize = 500 * 1024 * 1024
}
remote(HttpBuildCache) {
url = 'https://cache.team.example.com/cache/'
isPush = System.getenv('CI') == 'true'
connectionTimeout = 10_000
readTimeout = 120_000
maxSimultaneousConnections = 12
credentials {
username = 'build'
password = System.getenv('CACHE_PASSWORD') ?: ''
}
}
}
稳定运行建议:在 CI 构建机中,若远程缓存后端不可用,构建不应该失败。请使用
push = true 配合 org.gradle.caching.remote.enabled=true,并监控响应状态。推荐在缓存节点前加负载均衡与健康检查。