第1章 离线环境规划与缓存目录设计

离线构建的核心挑战在于如何在无网络条件下精确、高效地管理依赖缓存。本章将引导你设计一套结构清晰、支持多仓库隔离、可适配不同存储介质的离线缓存目录体系。

1.1 缓存总目录结构

Gradle 默认缓存位于 ~/.gradle/caches,但离线环境下需要独立且可迁移的目录。推荐采用层次化目录结构:

offline-cache/
├── metadata/           # 仓库元数据索引
│   ├── maven-central/
│   ├── jcenter/
│   └── custom-repo/
├── modules/            # 实际依赖模块
│   ├── maven-central/
│   ├── jcenter/
│   └── custom-repo/
├── transforms/         # 构建转换缓存
├── native/             # 本地库缓存
└── config.properties   # 缓存配置

1.2 分仓隔离策略

多仓库共存时,若混放可能导致坐标冲突或版本混乱。分仓隔离通过为每个仓库分配独立子目录,避免命名冲突,同时便于按仓库逐批更新。

具体实现方案:

  • 仓库标识化:使用仓库 URL 的哈希或简化名称作为子目录名。
  • 层级映射:每个仓库内部按 group/artifact/version/ 三级存储。
  • 元数据独立:metadata/ 子目录存放该仓库的 maven-metadata.xml 等索引文件。
仓库类型子目录示例备注
Maven Centralmodules/maven-central/官方仓库
JCentermodules/jcenter/已停用,示例保留
私有 Nexusmodules/nexus-mycompany/企业内网
本地 file repomodules/local-libs/本地目录
设计要点:分仓隔离简化了权限控制和同步策略。例如仅对 modules/nexus-mycompany/ 目录设置只读,防止意外覆盖。

1.3 存储介质选择与影响

缓存读写性能直接受存储介质影响。下表对比常见媒介:

介质顺序读写随机读写容量推荐场景
NVMe SSD极高极高256GB~2TB核心开发机
SATA SSD高中120GB~1TBCI 节点
HDD低低1TB~10TB冷存储备份
NFS中(网络决定)低共享团队共享缓存
性能警告:NFS 在大量小文件操作(如 Gradle 解压 JAR)时延迟显著。若必须使用,确保挂载参数 noatime、nodiratime,并开启 actimeo=30 减少属性查询。

1.4 实现流程:搭建离线缓存目录

  1. 创建根目录:mkdir -p /opt/gradle-offline-cache
  2. 按分仓隔离原则建立子目录:
mkdir -p /opt/gradle-offline-cache/{metadata,modules,transforms,native}
mkdir -p /opt/gradle-offline-cache/metadata/maven-central
mkdir -p /opt/gradle-offline-cache/modules/maven-central
  1. 创建配置文件(YAML 或 Properties):
# /opt/gradle-offline-cache/config.properties
cache.base=/opt/gradle-offline-cache
repo.isolation=true
repo.maven-central.url=https://repo1.maven.org/maven2
repo.jcenter.url=https://jcenter.bintray.com
# 若使用 NFS,可指定
cache.fs.noatime=true
  1. 验证目录结构:
tree /opt/gradle-offline-cache -L 2

1.5 目录结构示意图

离线Gradle缓存目录结构 offline-cache/ metadata/ modules/ transforms/ maven-central/ jcenter/ mycompany/ 说明: 每个仓库子目录内按 group/artifact/version 组织,元数据存放 metadata/ 下的对应索引。

1.6 调试与验证

使用 Gradle 命令行指定缓存目录进行测试:

gradle build --offline --cache-dir /opt/gradle-offline-cache --no-daemon --info 2>&1 | grep -i "cache"

若发现依赖缺失,检查:

  • 缓存目录是否存在对应坐标路径?
  • config.properties 中的 repo.isolation 是否开启?
  • 存储介质的磁盘空间是否充足?

1.7 常见错误与性能优化

常见错误:
  • “Could not resolve all dependencies” — 缓存目录未正确挂载或分仓子目录缺失。
  • NFS 挂载后构建缓慢 — 检查 actimeo 和 noatime 挂载参数。
  • Permission denied — 缓存目录权限不足,建议使用 chmod -R 755。
性能优化:
  • 优先使用本地 NVMe SSD 作为主缓存,HDD 或 NFS 仅用于备份。
  • 启用 Gradle 的 --parallel 和 --max-workers 并行解压。
  • 定期清理过期依赖(gradle cleanBuildCache 或手动删除 metadata/ 下冗余索引)。
  • 为 NFS 启用缓存代理(如 cachefilesd)减少网络往返。