4. 搭建Nexus代理缓存仓库:Nexus Raw Proxy配置、Gradle仓库URL绑定

4.1 原理概述

Nexus Raw Proxy 是 Sonatype Nexus Repository 中用于代理 Maven / Gradle 依赖的核心仓库类型。在离线或受限网络环境下,它位于 Gradle 构建环境与远程公共仓库(Maven Central、Google Maven、Gradle Plugin Portal)之间,充当本地缓存代理层,避免每次构建都重复下载相同的工件。

核心代理链路:

Gradle 构建 → repositories 中配置的 Nexus Raw Proxy URL → Nexus 接收请求 → 检查本地 Blob Store 缓存 → 命中则直接返回;未命中则从上游远程仓库拉取 → 缓存到本地后返回给 Gradle。

Raw Proxy 与 Hosted(托管)仓库的关键区别在于:Raw Proxy 不存储永久副本,而是基于 LRU(最近最少使用)策略保留缓存;而 Hosted 仓库用于存放组织内部私有构件,需要手动上传或通过 CI 推送。

特性Raw Proxy(代理缓存)Hosted(托管仓库)
数据来源自动从远程拉取手动上传或 CI 推送
缓存策略LRU + TTL(可配置最大保留天数)永久保存,需显式删除
适用场景代理 Maven Central、Google Maven 等公共仓库存放组织内部二方库、SNAPSHOT 包
离线可用性已缓存的工件可离线使用,未缓存则报错全部可用(前提是已上传)

4.2 实现流程

搭建 Nexus Raw Proxy 并完成 Gradle 绑定的完整流程分为 5 个步骤,从 Nexus 管理界面配置开始,到 Gradle 构建验证结束。

  1. 创建 Raw Proxy 仓库:在 Nexus 管理控制台新增一个 raw-proxy 类型的仓库。
  2. 配置远程存储地址:填入上游公共仓库的 base URL(如 https://repo1.maven.org/maven2/)。
  3. 绑定 Blob Store:指定用于缓存工件的存储后端(建议使用独立 Blob Store 以隔离不同代理仓库的缓存)。
  4. 配置 Gradle 仓库 URL:将构建脚本中的 repositories URL 指向 Nexus Raw Proxy 的公开地址。
  5. 验证代理缓存:执行 Gradle 构建,观察 Nexus 的访问日志与 Blob Store 增长情况。
Nexus Raw Proxy 配置绑定与代理流程 Gradle 构建 开发 / CI 环境 Nexus Raw Proxy 代理缓存仓库 缓存命中? SHA1 对比 本地缓存 Blob Store 远程上游仓库 Maven Central / Google 依赖返回给 Gradle ① 配置 URL 绑定 ② 代理请求 ✅ 命中 ❌ 未命中 ③ 回填缓存 Gradle 仓库配置示例 repositories { maven { url "https://nexus.intranet/ repository/maven-public/" } } Nexus Raw Proxy 配置要点: • Name: maven-central-proxy • Remote Storage: https:// repo1.maven.org/maven2/

4.3 关键配置参数

在 Nexus 管理界面创建 Raw Proxy 仓库时,以下参数直接影响代理行为和缓存效率:

参数推荐值 / 说明作用
Name如 maven-central-proxy仓库标识,Gradle 通过 URL 中的路径引用
Remote Storagehttps://repo1.maven.org/maven2/上游远程仓库地址,支持 HTTP / HTTPS
Blob Store建议新建 maven-cache 专用 Blob Store缓存物理存储位置,影响磁盘 I/O 隔离性
Maximum Component Age1440 分钟(24 小时)缓存有效期,超过后重新验证;离线环境可设为 -1 永不过期
Maximum Metadata Age1440 分钟元数据缓存 TTL,影响依赖解析的时效性
Negative Cache TTL60 分钟缓存不存在的工件记录,防止频繁回源请求
Routing Rule可配置白名单 / 黑名单规则控制允许代理的路径限制特定 groupId 或 artifactId 的请求
离线环境最佳实践:将 Maximum Component Age 设为 -1,禁止缓存过期;结合手动刷新策略,确保已缓存的依赖在断网后仍然可用。

4.4 Gradle 仓库 URL 绑定

在 Gradle 构建脚本中通过 repositories 块将依赖解析指向 Nexus Raw Proxy。绑定方式根据仓库类型分为 单一代理 和 Group 聚合 两种模式。

模式一:直接绑定单个 Raw Proxy 仓库

// build.gradle (Groovy DSL)
repositories {
    maven {
        url "https://nexus.internal.example.com/repository/maven-central-proxy/"
        // 如需认证:
        // credentials {
        //     username = 'deployer'
        //     password = 'your-password'
        // }
    }
    maven {
        url "https://nexus.internal.example.com/repository/gradle-plugin-proxy/"
    }
}

模式二:绑定 Nexus Group 仓库(推荐)

通过 Nexus Group 仓库将多个 Raw Proxy 聚合到同一个 URL 下,Gradle 只需配置一个入口:

// build.gradle.kts (Kotlin DSL)
repositories {
    maven {
        url = uri("https://nexus.internal.example.com/repository/gradle-group/")
        isAllowInsecureProtocol = false
    }
}

// settings.gradle.kts (插件管理)
pluginManagement {
    repositories {
        maven {
            url = uri("https://nexus.internal.example.com/repository/gradle-plugin-group/")
        }
    }
}

模式三:全局替换(init script 方案)

在 ~/.gradle/init.d/ 目录下放置 init 脚本,全局替换所有项目的仓库地址,适合团队统一管控:

// ~/.gradle/init.d/nexus-repos.gradle
allprojects {
    buildscript {
        repositories {
            maven { url "https://nexus.intranet/repository/gradle-group/" }
        }
    }
    repositories {
        maven { url "https://nexus.intranet/repository/gradle-group/" }
    }
}

4.5 调试与验证

配置完成后,通过以下命令和日志验证代理缓存是否正常工作。

步骤 1:测试 Nexus 连通性

# 使用 curl 测试 Raw Proxy 是否可访问
curl -I "https://nexus.internal.example.com/repository/maven-central-proxy/org/springframework/spring-core/5.3.30/spring-core-5.3.30.pom"

# 期望输出:HTTP/2 200 或 302(若已缓存则返回 200)

步骤 2:执行 Gradle 构建并观察缓存效果

# 第一次构建(从远程拉取并缓存)
./gradlew build --refresh-dependencies

# 第二次构建(应完全从本地缓存命中)
./gradlew build --offline

# 查看依赖解析详情
./gradlew build --info | grep "Downloaded\|Cached"

步骤 3:检查 Nexus 访问日志

# Nexus 默认日志路径
tail -f /opt/sonatype/nexus/log/request.log

# 日志示例(命中缓存时 status 为 200,且响应时间 < 10ms)
# 2025-04-09 10:15:30 [GET] /repository/maven-central-proxy/org/springframework/spring-core/5.3.30/spring-core-5.3.30.pom 200 5ms
注意:如果使用 --offline 模式构建时出现 Could not resolve external dependency 错误,说明该依赖尚未缓存到 Nexus 中。请先在联网环境下执行一次完整构建以填充缓存。

4.6 常见错误

错误现象可能原因解决方案
Connection refusedNexus 服务未启动或端口被防火墙拦截检查 Nexus 进程状态和端口监听:netstat -tlnp | grep 8081
401 UnauthorizedGradle 配置中缺少认证凭据或凭证错误在 repositories 块中添加 credentials 块,或使用匿名访问(需 Nexus 开启匿名权限)
404 Not FoundRaw Proxy 的 Remote Storage 地址配置错误确认 Remote Storage 是否指向正确的上游仓库 base URL
503 Service Unavailable上游远程仓库不可达(网络断开)检查 Nexus 服务器到外网的连通性;离线环境下确保依赖已提前缓存
Could not GET resource (SSL 证书错误)Nexus 使用自签名证书导致 Gradle 拒绝连接将 Nexus 证书导入 Gradle 信任库,或在 repositories 中配置 isAllowInsecureProtocol = true(仅测试环境)

4.7 性能与稳定性优化

针对离线环境和持续集成场景,从以下维度优化 Nexus Raw Proxy 的稳定性和缓存效率:

  • Blob Store 隔离:为每个 Raw Proxy 分配独立的 Blob Store,避免不同类型依赖的缓存互相干扰,也便于单独清理和迁移。
  • 缓存预热脚本:在联网窗口期内,使用 wget 或自定义脚本遍历项目的 gradle-dependencies.xml 或 pom.xml,强制 Nexus 缓存所有关键依赖:
#!/bin/bash
# cache-warmup.sh — 批量预热 Gradle 依赖到 Nexus Raw Proxy
BASE_URL="https://nexus.intranet/repository/maven-central-proxy"
DEP_LIST="dependencies.txt"  # 每行一个 Maven 坐标: group:artifact:version

while IFS= read -r coord; do
  # 将 group:artifact:version 转换为路径
  group=$(echo "$coord" | cut -d: -f1 | tr '.' '/')
  artifact=$(echo "$coord" | cut -d: -f2)
  version=$(echo "$coord" | cut -d: -f3)
  url="${BASE_URL}/${group}/${artifact}/${version}/${artifact}-${version}.pom"
  echo "Warming: $url"
  curl -s -o /dev/null -w "%{http_code}\n" "$url"
done < "$DEP_LIST"
  • Negative Cache 调优:将 Negative Cache TTL 从默认的 60 分钟提升到 1440 分钟(24 小时),减少重复查询不存在的工件。
  • 磁盘监控与清理:配置 Blob Store 的 Soft Quota 限制最大缓存容量(如 50 GB),当磁盘使用率超过阈值时自动触发 Compact Blob Store 任务释放空间。
  • 高可用部署:在集群环境中使用 Nexus 实例 + 共享 NFS 存储,或启用 Nexus 自带的 High Availability 模式,避免单点故障导致整个 CI 流水线阻塞。
稳定性指标建议:在离线环境中,配置完成后应至少通过 ./gradlew build --offline 验证 全部依赖从 Nexus 缓存命中,零外网请求。如命中率低于 95%,建议使用 --refresh-dependencies 模式补全缓存。