4.3 私服选型:Nexus 与 Artifactory 对决 本节摘要:私服以代理缓存加速依赖获取、以内网托管承载自研构件、以仓库组统一入口。Nexus 与 Artifactory 是两大主流方案,分别以 proxy、hosted、group 与 local、remote、virtual 三类仓库实现同一套语义。本节给出概念对照、选型矩阵与落地配置要点。 没有私服的团队在过什么日子 risk-engine 团队二十人,没有私服时的日常:每次新人入职全量从中央仓库下载依赖,内网出口带宽被同一批构件反复打;自研的 rule-sdk 靠共享目录分发,版本口径全靠吼;某天中央仓库一个构件被作者删除,全团队构建集体趴窝(左位移类事件在开源史上真实发生过)。
本节摘要:私服以代理缓存加速依赖获取、以内网托管承载自研构件、以仓库组统一入口。Nexus 与 Artifactory 是两大主流方案,分别以 proxy、hosted、group 与 local、remote、virtual 三类仓库实现同一套语义。本节给出概念对照、选型矩阵与落地配置要点。
risk-engine 团队二十人,没有私服时的日常:每次新人入职全量从中央仓库下载依赖,内网出口带宽被同一批构件反复打;自研的 rule-sdk 靠共享目录分发,版本口径全靠吼;某天中央仓库一个构件被作者删除,全团队构建集体趴窝(左位移类事件在开源史上真实发生过)。
私服一次解决三件事:代理缓存(中央仓库的构件每人只取一次,之后全走内网缓存)、内网托管(自研构件有了正式的家,发布与引用走同一套坐标体系)、统一入口(开发者与 CI 只配一个地址,仓库路由策略集中管理)。此外它还是第 3.5 节供应链防线的物理载体——内外解析空间的隔离在私服上落地。
两大方案用不同的词讲同一件事,对照表先立起来:
| 语义 | Nexus 叫法 | Artifactory 叫法 | 作用 |
|---|---|---|---|
| 内部正式存放 | hosted 托管仓 | local 本地仓 | 自研 RELEASE 与 SNAPSHOT 的家 |
| 外部代理缓存 | proxy 代理仓 | remote 远程仓 | 代理中央仓等外部源 缓存命中不出内网 |
| 统一入口 | group 仓库组 | virtual 虚拟仓 | 一个地址聚合全部来源 按序检索 |

拓扑图右下角那行字是第 3.5 节防线的落地形态:仓库组的检索顺序里,内部托管仓排在公共代理仓之前,且公共代理仓绝不接受上传——同名构件的解析空间物理隔离,依赖混淆没有了入口。
两个方案都成熟可靠,选型差异在工程细节与生态倾向:
| 维度 | Nexus Repository | Artifactory |
|---|---|---|
| 上手与界面 | 界面朴素 功能直达 | 界面信息密度高 上手稍陡 |
| 仓库类型广度 | Maven 为主 Docker 与其他格式齐备 | 格式支持极广 多语言仓库事实标准之一 |
| 清理策略 | cleanup policies 内置按条件清理 | 内置清理计划 与存储回收配合 |
| 高可用 | 免费版单机 集群要商业版 | 集群与复制能力更强 商业版突出 |
| 生态协同 | 与 CI 基本盘顺滑 | 与研发效能平台类工具协同更深 |
| 授权倾向 | 社区版开放功能较多 | 核心可用 高级能力商业化明显 |
选型建议按团队现状分岔:纯 Java 技术栈、团队规模中小、想快速见效,Nexus 社区版的配置成本更低,一两个小时能上线;多语言仓库需求(Java 加前端加 Python 混合仓)、有预算、要高可用,Artifactory 的格式整合与复制能力值回票价。risk-engine 这类 Java 团队选了 Nexus,下一小节的配置要点以它为例,Artifactory 的仓库语义一一对应(group 对 virtual、hosted 对 local),迁移成本主要在权限与清理策略的重建。
迁移的真实工作量也交代一下,给"先选错后换"的团队一个预期:构件本体可以从旧私服批量导入(两套产品都支持从上游拉取回填缓存),权限模型要重建(两家的账号与角色体系不互通),清理策略要重新配(语义相同但配置界面不同),流水线里的仓库地址与 settings 的镜像地址要全局替换。按一个中型私服(几百个构件坐标、十几个权限角色)估算,迁移窗口一个周末足够,风险点集中在凭证同步——新私服上线而某台 CI 机器的 settings 没更新,就是一次教科书级的第 3.4 节断粮事故。
# 容器化部署(内网服务器示例) docker run -d --name nexus \ -p 8081:8081 \ -v nexus数据卷:/nexus-data \ 私有镜像源/library/sonatype/nexus3 # 首次启动后 默认管理员密码在数据卷的 admin.password 文件里 # 首登强制改密 然后建专用账号 按 deploy 与 read-only 分权
上线后的五件事清单:建 releases 与 snapshots 两个托管仓并关闭"允许重新部署"(releases 仓);建指向中央仓库的代理仓,内网机器从此不再直连外网;建仓库组,顺序为托管仓在前、代理仓在后;为流水线与开发者分别建权限账号;配清理策略(快照仓只留 30 天,代理缓存按总量上限滚动)。完成后再回到开发机,settings 里把仓库组配为镜像(第 4.4 节详解镜像语法),全团队的下一次构建就已经走内网了。
验收私服是否真正接管了补给线,跑三条探针命令:
# 探针一:清掉某个常用构件的本地缓存 重新解析 mvn dependency:resolve -X 2>&1 | findstr "Downloading" # 日志里的来源应显示私服仓库名 而不是 central # 探针二:验证内网构件的解析空间隔离 # 尝试从公共代理仓路径访问内部构件 应返回 404 # 内部坐标只可能命中托管仓 # 探针三:发布演练 往快照仓 deploy 一个测试构件 # 再从另一台机器解析 确认时间戳快照可被正确拉取
三条探针全绿,补给线才算验收通过。多数团队跳过验收直接宣布上线,然后在某个周一早晨发现镜像配置写错、全员构建走了外网一整周——带宽账单之外,更贵的是那段"我们以为在内网"的错觉。
💡 关键直觉:私服的隐性收益是"观测"。所有构件的进出都过它,谁在用什么版本、哪个废弃构件再无人引用、快照仓里谁最活跃,后台报表一目了然。第 3 章靠依赖树做的存量清点,在私服数据面前从考古变成了查询。有了这份查询能力,季度体检(上一节的卫生学三问)也就有了现成的数据源。
补给线建好了,最后一环是把每台机器接到这条线上——下一节讲 settings.xml:镜像、凭证、Profile 三段的语法与它们出错时的排法。