资讯详情

Maven私服迁移升级:从Nexus 2.11.4到3.12.0实战

📅 2026/9/16 18:54:37 | 华诺云谱 👁 阅读
Maven私服迁移升级:从Nexus 2.11.4到3.12.0实战
搞Maven私服的团队几乎都会在某一天面对同一个决定那台跑了好几年的Nexus 2.x到底要不要换。我所在的团队手里就是一台上古机器Nexus Repository Manager 2.11.4装在CentOS 6的虚拟机里JDK还是1.7仓库目录已经涨到快200G。它没坏也还能用但每次想加个Docker仓库、想接个npm私包、想让新人用浏览器顺手查依赖它就露怯了。于是我们把目标锁定在Nexus 3.12.0做了一次完整迁移升级。这篇就把从盘点、备份、装新库、搬数据到改客户端配置的全过程拆开讲尤其是那些官方文档一笔带过、实操时却能让人卡半天的细节我会尽量说透。不管你手上是2.11还是2.14只要准备往3.x走这套思路都能直接照着抄。1. 先想清楚为什么非得从Nexus 2.11.4挪到3.12.01.1 2.x和3.x在仓储模型上的根本分野很多人以为Nexus升级就是换个版本号装完把数据拷过去就完事。真上手才发现2.x和3.x底层是两套完全不同的仓储模型这也是迁移复杂度远超点两下升级的根源。在Nexus 2.x里所有仓库共享一个大的storage目录每个仓库有自己的子目录路径是sonatype-work/nexus/storage/repo-name。代理仓库、宿主仓库、仓库组都是在这套目录结构上逻辑区分。数据库用的是OrientDB元数据和文件分开存。到了Nexus 3.x引入了**Blob Store二进制存储这个概念所有制品文件先落到blob store里再用数据库记录索引关系。数据库换成了OrientDB的3.x版本同时新增了仓库格式Format**这一层抽象——maven2、raw、docker、npm、nuget等每种格式有自己的能力和配置项。换句话说2.x里仓库就是核心单位3.x里格式blob store仓库三层配合才是完整概念。这个差异直接决定了迁移方式不能简单拷目录因为两边的存储组织方式不一样索引也对不上。必须用官方的迁移工具或者走重新上传的路子。1.2 不升级会持续踩到的几个真实痛点我列几个把我们逼上梁山的实际问题你看看是不是也中招。Docker私仓无处安放2.x时代要托管Docker镜像得额外搭registry或者上别的组件管理割裂。3.x原生支持docker格式仓库一个Nexus全搞定。浏览器查询体验太差2.11.4的Web界面还是老式布局查一个依赖的版本列表、看一个jar的依赖树翻页翻得人烦躁。3.x的界面和搜索能力强了不止一个档次。新格式接入困难团队陆续要用npm、用raw仓库存放发布包2.x要么不支持要么配置起来别扭。安全更新停滞2.11.4是2016年前后的版本后续基本没有安全补丁了放在内网也得考虑风险面。权限模型粗糙2.x的权限颗粒度和3.x的privilege/role体系相比做精细化管控很吃力。提示如果你的Nexus 2.x只是当个纯Maven代理用团队规模也小那升级的紧迫性确实不高。但只要涉及多格式、多团队、权限细分3.x带来的收益会非常明显。2. 迁移前必须做的资产盘点与备份2.1 先把2.x里的仓库家底摸清楚动手前第一件事不是装新库而是把老库彻底盘一遍。我建议登录Nexus 2.11.4的管理台进Repositories页面把所有仓库按类型列一张表。你需要搞清楚三类信息。第一类是仓库清单每个仓库的名称、类型proxy/hosted/group/virtual、格式Maven/…、远程地址如果是proxy。第二类是数据体量每个仓库大致占用多少空间用du -sh在sonatype-work/nexus/storage下逐个看。第三类是使用方哪些项目、哪些团队的settings.xml里指向了这个仓库谁有发布权限。我当时的盘点结果大致是这样供你参考对照仓库名类型用途体量是否迁移centralproxy代理Maven中央仓120G迁移可重建索引releaseshosted内部正式发布45G必须迁移snapshotshosted内部快照30G必须迁移thirdpartyhosted第三方手工上传8G必须迁移publicgroup对外统一入口-逻辑重建这张表看似简单但它是后面所有决策的依据。比如我发现central这个代理仓库占了120G但其实完全没必要迁移——新库重新挂一个proxy指向同一个上游缓存慢慢重建就行省下大量迁移时间。2.2 备份的三种粒度和取舍备份不是简单地tar一下目录。我把它分成三个粒度各有适用场景。粒度一整机快照。如果2.x跑在虚拟机上直接对VM做一次快照或克隆。这是最省事、最保险的方式出任何问题都能秒回滚。我们第一步就做了这个成本几乎为零。粒度二storage目录全量拷贝。把sonatype-work/nexus整个目录打包拷出来。这一步是为了防止迁移过程中数据损坏。注意拷之前最好先停服务或者用Nexus自带的任务做一致性备份避免文件在拷贝时还在被写入。# 停掉Nexus 2.x服务 service nexus stop # 打包整个work目录 tar -czvf nexus2-backup-$(date %Y%m%d).tar.gz /opt/sonatype-work/nexus # 确认包完整后重启 service nexus start粒度三关键仓库单独导出。对于releases、snapshots这些自研制品除了整体备份我还额外把它们的storage目录单独又拷了一份。原因很简单这几个仓是团队几年积累的正式制品丢了没法重建值得单独保险。注意备份tar包一定要做完整性校验tar -tzf看能否正常列出内容并且异地存一份。我见过有人备份完发现包是坏的等到要恢复时才发现那就真的没救了。2.3 一个容易被忽略的坑Nexus 2.11.4的版本门槛这块是重中之重直接决定你能不能用官方工具。Nexus 3.x自带的Upgrade Agent升级代理是官方推荐的迁移方案但有个硬性前提源端Nexus 2的版本必须不低于2.14.8。而我们手上是2.11.4低于这条线官方工具根本不认。这意味着你有两条路可走先升2.x再说把2.11.4原地升级到2.14.8或更高的2.14.x然后再用Upgrade Agent迁移到3.12.0。好处是能用官方工具、过程相对标准代价是要多做一次2.x内部升级百年老库升级本身也可能踩坑。绕开官方工具用文件系统REST API或脚本把制品重新批量推到3.x的新仓库里。麻烦但对老版本最直接。我们最终选了组合拳先把2.11.4升到2.14.8跑通Upgrade Agent做主体迁移再用脚本补齐一些遗漏。下面两条路我都会讲。3. 把2.11.4先原地升到2.14.83.1 为什么这一步不能跳过有人会问既然要迁到3.x为什么还折腾一次2.x升级答案就在上面那条版本门槛。2.14.8是Upgrade Agent支持的最低源版本而且2.14.x对后续迁移的数据格式做了不少兼容处理。跳过这一步要么官方工具直接报错要么迁移出来的数据缺斤少两。2.x内部的小版本升级相对温和因为它们共用同一套存储模型升级主要是替换程序目录、更新数据库schema。只要按顺序操作风险可控。3.2 原地升级的具体步骤升级前再确认一次备份已经到位。然后按下面的流程走。# 1. 停止旧的2.11.4服务备份原程序目录 service nexus stop cd /opt mv nexus nexus-old-2.11.4 # 2. 下载并解压2.14.8 # 注意这里用你们内部允许的方式获取安装包 tar -xzvf nexus-2.14.8-01-bundle.tar.gz ln -s nexus-2.14.8-01 nexus # 3. 关键点work目录不要动指向原来的sonatype-work # nexus 2.x升级时storage和数据库都复用原work目录几个必须注意的点wwwroot和程序目录换新但sonatype-work保持不动。升级的本质是新版程序读老版数据程序目录替换掉就行数据目录原封保留。JDK版本要匹配。2.14.8对JDK的要求比2.11.4高建议用JDK 8。升级前先把JAVA_HOME指到合规的JDK上。启动后看日志确认schema迁移成功。2.x升级时数据库会做schema更新日志里会有一大段迁移记录务必看到started之类的成功标志再放心。启动新版本后登录界面确认仓库、用户、权限都还在随便拉一个依赖验证代理仓正常。3.3 升级后的一次全面自检原2.x升级完成后先别急着迁3.x做一轮自检检查项验证方式预期结果仓库列表完整Repositories页面与升级前一致用户和权限Users/Roles页面账号可正常登录代理仓可用拉取一个未缓存的依赖能成功代理下载发布仓可用对一个测试项目执行deploy制品成功上传定时任务Scheduled Tasks页面原有任务都在这一轮自检过了才具备迁移到3.x的条件。别嫌麻烦这等于给老库做了次体检能提前暴露很多隐藏问题。4. 装Nexus 3.12.0并规划新的仓储布局4.1 Docker部署还是裸机部署3.x的安装摆在面前的选择无非两种Docker镜像跑或者裸机解压跑。我两个都评估过最后选了裸机部署原因很现实。Docker部署的好处是干净、可复制、升级方便。但Nexus的Blob Store默认放在容器里要迁到3.x后管理200G级别的数据得把blob store挂到宿主机volume上还要考虑文件权限、UID映射这些事。而且当时我们内网的Docker环境并不成熟运维同事对容器存储的排障经验有限。裸机部署则是老路子程序目录和work目录分开blob store直接落在大盘上运维熟、排查快。对动辄几百G的仓库来说本地磁盘IO也更可控。所以我建议数据量大、追求稳定可控就裸机追求环境一致性和快速重建就Docker。裸机部署的核心步骤# 需要JDK 8环境 java -version # 解压3.12.0 tar -xzvf nexus-3.12.0-01-unix.tar.gz mv nexus-3.12.0-01 nexus3 # 程序目录下自带sonatype-work # 启动 cd nexus3 ./bin/nexus start默认端口8081首次访问会走一段初始化配置。3.x和2.x不一样它不再内置默认的admin/admin123那种一眼可见的弱口令而是生成一个随机密码放在sonatype-work/nexus3/admin.password里首次登录强制修改。这个改动是好事安全层面正向。提示要是忘记admin密码3.12.0可以停服务后删掉sonatype-work/nexus3/admin.password重启会重新生成一个新密码文件。这个技巧后面排查会用到。4.2 按Maven习惯规划仓库和Blob Store3.x新建仓库前先想清楚Blob Store怎么规划。Blob Store是物理存储单元一个仓库必须挂在一个blob store上一个blob store可以托管多个仓库。我的规划原则是按生命周期和用途分组别全塞一个blob store里。理由有两点一是备份和迁移时可以按blob store粒度操作灵活二是不同类型仓库的访问频率差异大分开有利于后续做磁盘层面的调优。我们建了两个blob storemaven-blob托管所有Maven相关仓库releases、snapshots、central、thirdparty。docker-blob后续托管Docker仓库磁盘策略不同。然后建Maven仓库。3.x里对应2.x的典型布局是这样映射的2.x仓库3.x对应3.x格式类型centralmaven-centralmaven2proxyreleasesmaven-releasesmaven2hostedsnapshotsmaven-snapshotsmaven2hostedthirdpartymaven-thirdpartymaven2hostedpublicmaven-publicmaven2group关键配置点hosted仓库的Version policy要选对。releases选Releasesnapshots选Snapshot选错了会导致发布失败。proxy仓库的上游URL照抄2.x里的Remote Storage Location比如中央仓填https://repo1.maven.org/maven2/。group仓库把前面几个都加进member列表让客户端只连一个地址就能同时拿到代理和自研制品。4.3 别忘了配一个上游镜像加速内网私服代理中央仓如果直连官方源下载速度经常惨不忍睹。我们按常见实践把proxy仓库的上游指向了国内稳定的镜像地址提速非常明显。这个改动和迁移本身无关但既然重建仓库顺手把它做了。具体操作就是在proxy仓库的Remote Storage里换成镜像地址或者在仓库的HTTP配置里加一层。要注意镜像地址的可用性和同步频率别配了一个三天两头抽风的源。我们当时的做法是同时保留了官方源作为备用主用镜像。5. 用Upgrade Agent把2.14.8的数据搬进3.12.05.1 Upgrade Agent到底怎么工作Upgrade Agent的原理是在Nexus 3这一侧作为客户端主动去连接Nexus 2那一侧通过一套内部协议把仓库定义、制品文件、元数据拉过来。它不是拷目录而是重新导入所以两边数据库结构不同也不影响。工作流程大致是在Nexus 3里启动升级任务→任务通过HTTP连到2.x的升级端点→拉取仓库清单→逐仓库拉取制品→在3.x里重建。5.2 配置和执行升级任务的完整流程在3.12.0里升级入口在设置里Administration → System → Upgrade。执行前要准备好几个参数源Nexus 2的地址形如http://老库IP:8081。访问凭据一个在2.x里有足够读权限的账号。用admin或者专门开个只读账号都行。要迁移的仓库可以全选也可以只挑需要的。我们只勾了releases、snapshots、thirdpartycentral那种大代理仓不迁。配置好后启动任务然后就是等。迁移时间取决于数据量45G左右的自研仓库我们跑了几个小时。期间可以看进度条和日志。注意迁移过程中2.x服务要保持运行且尽量避免有人往里写。最好提前发个通知让所有人暂停发布把2.x置为只读状态。一边迁一边写会造成数据不一致。5.3 迁移完成后的逐项校验迁移任务显示100%不代表万事大吉一定要逐项验证。我列了张校验清单校验项方法通过标准制品数量对比2.x和3.x的仓库文件数数量基本一致元数据完整3.x里打开某仓库看版本列表maven-metadata.xml齐全依赖可解析用一个老项目指向新库构建依赖全部下载成功快照时间戳检查snapshot的timestamp版本与实际发布一致制品校验和抽查几个jar的sha1与2.x一致其中制品校验和这步最关键。迁移偶尔会出现大文件截断或损坏抽几个关键包的SHA1对比一下能及早发现。6. 改客户端Maven和settings.xml的适配6.1 settings.xml里最该改的三处服务端迁完了客户端不改配置一样白搭。Maven用户的核心配置就在settings.xml重点改三处。第一处mirror镜像。如果原来用mirrorOf*/mirrorOf把请求都导向2.x的public组现在要改成3.x的maven-public地址。mirrors mirror idnexus-public/id nameInternal Nexus Public/name urlhttp://新库IP:8081/repository/maven-public//url mirrorOf*/mirrorOf /mirror /mirrors注意3.x的仓库URL路径里多了/repository/这一段这是和2.x最直观的区别很多人改地址时漏掉它结果死活拉不到东西。第二处server发布凭据。deploy用的账号密码要更新。servers server idnexus-releases/id usernamedeploy-user/username password对应密码/password /server server idnexus-snapshots/id usernamedeploy-user/username password对应密码/password /server /servers第三处profile里的仓库和pluginRepository。把发布仓库指向3.x的releases和snapshots。6.2 项目的pom.xml里要动的地方服务端地址变了每个要发布的项目pom里的distributionManagement也得跟着改。distributionManagement repository idnexus-releases/id urlhttp://新库IP:8081/repository/maven-releases//url /repository snapshotRepository idnexus-snapshots/id urlhttp://新库IP:8081/repository/maven-snapshots//url /snapshotRepository /distributionManagement这里的id必须和settings.xml里server的id一致否则Maven找不到对应凭据会报401。这是超高频的坑。6.3 批量替换的思路项目一多一个个改pom不现实。我们的做法是先梳理所有项目的distributionManagement和settings.xml里的旧地址。用脚本批量把旧地址替换成新地址。挑几个有代表性的项目跑mvn clean deploy验证。# 示例在所有pom.xml里把旧地址换成新地址 find . -name pom.xml -exec sed -i \ s|http://老库IP:8081/nexus/content/repositories/releases|http://新库IP:8081/repository/maven-releases|g {} \;替换完一定要再用mvn dependency:resolve跑一遍依赖解析确认代理仓和自研仓都通。7. 迁移路上踩过的坑与排查思路7.1 版本门槛2.11.4直接被Upgrade Agent拒绝这是第一个大坑。我们一开始想直接从2.11.4迁到3.x结果任务一启动就失败日志里明确提示源版本过低。折腾半天才确认那条2.14.8的门槛。解决办法就是前面说的先原地升到2.14.8。这个坑的教训是动手前先查官方对源版本的最低要求别想当然。7.2 仓库URL少了/repository/导致全面404客户端改造阶段有同事只把IP换掉路径还是老的.../content/repositories/...。3.x的路径结构变了正确格式是.../repository/仓库名/...。表现是所有依赖解析返回404或者干脆连不上。排查方法很简单用浏览器直接打开那个URL看能不能看到目录列表或返回正常。报错现象可能原因排查动作全部依赖404URL路径写错浏览器直接访问验证路径401未授权server的id与pom不匹配核对id一致性deploy被拒往release仓推snapshot检查版本策略和包类型个别包下载失败制品迁移损坏对比SHA1重新上传7.3 快照仓库策略配错导致发布失败有一次测试项目发布死活失败日志说cannot deploy snapshot to release repository。原因是我们把hosted仓库的Version policy配成了Release而项目推的是SNAPSHOT版本。改回Snapshot策略后正常。这个错误在3.x新建仓库时特别容易犯因为界面默认值和你的预期不一定一致。7.4 忘了admin密码怎么救3.x的随机密码文件机制很安全但运维交接时容易丢。如果丢了停服务删掉sonatype-work/nexus3/admin.password重启会重新生成。前提是你还能停服务、有文件系统权限。7.5 大文件迁移中断迁移一个上百M的大jar时任务卡住甚至报错。这通常是网络中断或超时导致。解决思路是提高超时配置、分批迁移、或者对该仓库用重新上传的方式补齐。我们后来对个别大包走了手动mvn deploy重传。8. 迁移之后还能做的几件事8.1 清理历史包袱迁到3.x是个绝佳的清理时机。2.x里积累了大量没人用的老快照、测试阶段传错位置的包。我们借机清了一轮把超过一年没被引用的snapshot按规则清理把误传到releases的snapshot挪走。库干净了查询和备份都轻松。清理时可以用Nexus自带的清理任务Cleanup Policies配置规则让系统自动删过期快照省得手动维护。8.2 把权限体系重做一遍3.x的privilege/role/user三层权限模型比2.x精细得多。迁移完正好借机重构按团队分role比如dev-team-a-release、dev-team-b-snapshot。发布权限单独授予别让所有人都能往releases推。代理仓只给读权限杜绝误删缓存。8.3 加监控和告警迁移完成后我们给Nexus加了基础监控磁盘使用率、服务存活、以及一个简单的HTTP健康检查。仓库这东西平时没人管一出问题就是全员构建失败早点发现比事后救火强。# 简单的存活探测 curl -s -o /dev/null -w %{http_code} http://新库IP:8081/service/rest/v1/status返回200就说明服务正常可以挂到监控系统里定时探测。我个人在整个迁移过程中最大的体会是这套活儿的技术难点不在怎么迁而在迁之前想没想清楚。版本门槛、仓库取舍、客户端地址变更这三件事只要提前规划到位真正执行起来反而很顺。还有一点小经验——迁移完成后别急着把老库下线让它以只读方式再挂一两个月。中间如果发现哪个项目漏改了配置、哪个制品没迁全老库还能临时顶上。等确认新库彻底稳了再优雅地把2.x退役。这样整个升级过程团队的构建流水线几乎是零感知切换比那种一夜之间换库的做法稳妥太多了。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。