第4章 远程缓存配置与集成:HTTP远程缓存、使用Redis/Artifactory作为后端、认证配置、安全传输

4.1 远程缓存的角色与架构

远程缓存是 Gradle 构建缓存体系的关键扩展,允许团队共享构建产物,避免重复编译。其核心架构如下:

远程缓存架构图 Gradle 构建实例 本地缓存代理 (合组合用) 远程缓存后端 HTTP 服务器 / Artifactory Redis / 对象存储 HTTPS 传输 安全层 基础认证 / API TLS / 证书验证 策略注入 缓存条目存储 TAR/GZip 压缩包
建议:远程缓存最适合持续集成(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 是企业级缓存后端,集成了通用制品仓库与构建缓存。配置步骤:

  1. 在 Artifactory 创建 通用仓库(Generic Repository)作为缓存目录。
  2. 启用 Artifactory 的 X-Gradle-Cache-Key 头支持(部分版本需额外插件)。
  3. 在 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 NodeHTTP 代理 + 分层缓存端口 5071,--backend redis
Gradle 端指向 Nodehttp://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 / Nexusheader '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 证书。常见配置:

  1. 使用受信任的 CA 签发证书(推荐生产环境)。
  2. 自签名证书 时,需要将证书导入 Java 信任库:
    keytool -import -trustcacerts -file cache-cert.pem -keystore $JAVA_HOME/lib/security/cacerts -alias gradle-cache
  3. 禁用证书验证(仅开发环境,不推荐):
    // 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.connectionTimeoutHTTP 连接超时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,并监控响应状态。推荐在缓存节点前加负载均衡与健康检查。