ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Nexus 2.11.4迁移升级至3.12.0:Maven私库实战

Nexus 2.11.4迁移升级至3.12.0:Maven私库实战 手上这套 Nexus 2.11.4 跑了几年里面塞满了 maven 私库的各种 Releases、Snapshots、第三方包和代理缓存一直没人敢碰。直到 JDK 升级、磁盘告警、新项目要 npm 和 docker 镜像源才发现继续留着它的成本已经比迁移更高。这篇文章就是我把一套线上运行多年的 maven 私库从 Nexus 2.11.4 迁移升级到 Nexus 3.12.0 的全过程记录包括路线选型、容量估算、升级代理的实际用法、脚本兜底方案、客户端 settings.xml 的改动点以及中途踩到的各种坑。适合手上有老 Nexus 2 环境、又必须往前走一步的运维和中间件同学也适合刚接手私库、还在搞清楚 maven 仓库是怎么一回事的人。我不会只讲点几下就完成了重点讲每一步为什么这么做以及哪些地方一旦做错就得重来。1. 迁移这件事的整体判断与路线选型1.1 2.11.4 到底卡在哪里为什么非动不可Nexus 2.11.4 是 Nexus 2 系列的末期版本本身稳定性没什么大问题真正让人难受的是它背后的生态已经停更。它只能管 Maven 这一类仓库格式想给前端团队开一个 npm 私库、给容器团队开一个 docker registry就得再装一套别的服务账号体系、权限模型、备份策略全部割裂。而我们这边的实际需求很直接前端的 node_modules 想走内网、镜像构建想从内网拉基础镜像、Java 那边的老依赖又必须保留三个需求叠在一起Nexus 2 完全没有办法承接。另一个绕不开的点是 Java 运行时。Nexus 2 的部署环境是 JDK 7/8 时代的产物随着服务器统一往更高版本的 JDK 走旧进程的兼容性开始变成隐患。再加上 Nexus 2 的搜索和浏览界面在老浏览器上表现越来越差新人接手时连这个依赖到底在哪个仓库都要翻半天。这些问题单看都不致命堆在一起就变成一个结论与其继续给老系统打补丁不如一次性换到 Nexus 3把 Maven、npm、docker 都收进同一个实例里管。注意迁移是单向的。Nexus 3 没有官方的降级回 Nexus 2通道所以真正动手之前Nexus 2 的数据目录必须有一份可用的冷备份这不是可选项。1.2 三条迁移路线原地升级、并行部署、纯脚本搬运我一开始把可能的路径全部列了出来对比之后才决定走哪条。路线做法优点风险与代价原地升级在旧机器上把 Nexus 3 装到新目录复用同一份数据省机器Nexus 2 与 Nexus 3 的数据结构完全不同实际上做不到复用此路基本不通并行部署新机器装 Nexus 3通过升级代理从旧实例拉数据旧库不动、可回滚、有官方工具需要双份磁盘、迁移窗口内要冻结写入纯脚本搬运直接读 Nexus 2 的存储目录用 REST 或 deploy 回灌不依赖官方工具、可控粒度慢、元数据容易丢、快照处理麻烦原地升级这条我很快就否掉了。Nexus 2 的存储是纯粹的文件树加上本地索引Nexus 3 换成了一套完全不同的元数据数据库加上分桶式的 blob store两者之间不存在版本覆盖式的升级关系。想省机器的人往往在这里踩坑把 Nexus 3 装到 Nexus 2 的目录里启动之后发现仓库列表是空的甚至把原来能用的旧实例搞坏。所以我走的是并行部署用新机器承接旧实例保持只读等到验证没问题再下线。这条路的代价是要多准备一台机器和一份磁盘空间但换来的是随时可以退回旧地址的能力——在私库这种一挂全公司都构建不了的场景里这个退路值这个钱。脚本搬运我没有放弃而是作为兜底方案准备着后面第 5 节会讲它的具体写法因为实际迁移时确实有几个仓库是官方工具搞不定、只能自己搬的。1.3 为什么落在 3.12.0 这个版本上版本选择上我没有追最新而是选了 3.12.0理由有三个。第一这个版本对 Maven 2 迁移的支持已经相对成熟升级代理的流程在这个阶段已经跑通社区里能查到的案例也最多。第二3.12.0 对 JDK 的要求就是 JDK 8跟我们现有的服务器基线完全对得上不需要为了一个私库去动整个 JDK 版本策略。第三再往后的版本会引入一些新的管理概念配置项和界面都变了团队里其他人上手成本会变高。版本这件事上我的建议是不要选太新的也不要停在最早的 3.0.x。3.0.x 的迁移工具在早期确实有过一批已知问题比如大仓库迁移中途断掉之后不好恢复而太新的版本你又得重新踩一遍别人没踩过的坑。3.12.0 属于中间那段该修的都修了、文档也齐了的区间对一次性的迁移任务来说是最合适的选择。2. 动手前的资产盘点与容量估算2.1 先把 Nexus 2 的仓库家底摸清楚迁移最容易出事的地方不是工具用错而是压根不知道自己有什么。我做的第一件事是登录 Nexus 2把 Repositories 页面里所有仓库列出来逐个记录类型、格式、是否被 group 引用。Nexus 2 里常见的仓库大致是这几类托管型比如团队自己 deploy 的 releases 和 snapshots还有手工上传的第三方包代理型比如指向中央仓库的代理和指向阿里云镜像的代理虚拟型也就是把上面这些聚合起来对外提供统一地址的 group。这一步的意义在于决定迁移顺序。我的策略是先迁代理型仓库再迁托管型的最后处理 group。原因很直接代理型仓库里的大量内容其实是缓存即使丢了也能重新从上游拉回来就算迁移失败影响也可控而托管型仓库里是团队自己发布的包很多老版本的上游根本找不回来一旦丢失就是永久损失必须放在网络和磁盘都验证稳定之后再动。盘点的时候还要顺手记下每个仓库的体积。在 Nexus 2 的存储目录下用du -sh逐个统计比在界面上看更准cd /data/nexus/sonatype-work/nexus/storage du -sh */ | sort -h跑完这条命令你会看到 releases、snapshots、thirdparty、central 这些目录各自占了多少。我这边光是中央仓库的代理缓存就有将近 90G团队自己发布的 releases 反而只有 30G 出头这个分布直接决定了我后面磁盘要怎么规划。2.2 磁盘和内存的账要提前算磁盘这块必须留足冗余因为迁移期间 Nexus 2 和 Nexus 3 是同时存在的两边的数据是双份。Nexus 3 的 blob store 除了内容本身还会有一套元数据数据库和索引文件实际占用通常会比原库略高一点。我的经验公式是新机器可用磁盘 ≥ 原库体积 × 1.5如果是那种代理仓库特别大的场景直接按 2 倍准备更稳妥。内存的账要算得更细一些。Nexus 3 是 JVM 应用堆内存之外还用了直接内存做文件传输的缓冲所以不能只看-Xmx。物理内存的分配思路是JVM 堆占三分之一到二分之一剩下的留给操作系统做文件缓存和直接内存。具体取值可以参考下面这张表是我在几个不同体量的环境上验证过的范围。数据总量建议 -Xms/-Xmx建议 MaxDirectMemorySize物理内存起点100G 以内4g4g8G100G 到 500G8g8g16G500G 以上16g16g32G提示堆内存不是越大越好。把-Xmx设到物理内存的 80% 以上剩下的内存不够做文件缓存反而会让大批量拉取依赖时的响应变慢甚至触发系统的内存回收导致进程假死。2.3 账号、权限、定时任务清单除了仓库内容还有三类软资产容易在迁移时被忽略。第一类是用户和角色。Nexus 2 里的用户如果只在本地库存在迁移工具是不会帮你带过去的需要在 Nexus 3 里重建或者干脆接入统一认证一次性解决。第二类是权限模型。Nexus 3 的权限粒度比 Nexus 2 细而且默认的匿名访问策略更严格。我在盘点时就明确了哪些仓库允许匿名读、哪些必须认证这个结论会直接影响迁移后客户端是否需要配置账号也决定第 6 节的 settings.xml 要怎么写。第三类是定时任务和清理策略。Nexus 2 里通常配了快照清理、索引重建这类计划任务这些任务的定义不会被迁移带过去需要在 Nexus 3 里重新配。别小看这一步我见过迁移完之后没人管快照清理半年后磁盘就满了。3. Nexus 3.12.0 的环境准备与落地部署3.1 JDK 与操作系统的前置条件Nexus 3.12.0 跑在 JDK 8 上最稳这一点没什么可商量的。我第一次试的时候用了更新的 JDK 版本启动脚本直接报错退出日志里是模块相关的异常——因为那个阶段的 Nexus 还没有适配新版本 JDK 的模块系统。所以环境准备阶段就把 JDK 8 装上并且用JAVA_HOME明确指出来不要让系统 PATH 里先撞到别的版本。export JAVA_HOME/usr/local/jdk1.8.0_xxx export PATH$JAVA_HOME/bin:$PATH java -version除了 JDK还有两个系统层面的参数要看文件句柄数和最大进程数。Nexus 3 在迁移大批量小文件时会同时打开很多句柄默认的 1024 很容易不够用。我在/etc/security/limits.conf里给运行 Nexus 的账号加了nofile 65536这个改动很小但能避免迁移到一半突然出现一堆莫名其妙的 IO 异常。3.2 安装包部署与目录规划安装包从官方渠道下载后解压到一个独立目录比如/opt/nexus-3.12.0-01然后用软链接/opt/nexus指过去方便后面升级时切换。数据目录不要放在安装目录里面这是我吃过亏的地方早期有人图省事把数据放在安装目录结果换版本时顺手把整个目录删了重建数据一起没了。目录规划我按这个结构走安装目录放程序数据目录单独挂一块盘放sonatype-work日志通过配置输出到一块独立的、不那么重要的盘上。这样做的好处是备份目标非常清晰只需要备份数据目录程序目录随时可以重新解压一份出来。tar -zxf nexus-3.12.0-01-unix.tar.gz -C /opt/ ln -s /opt/nexus-3.12.0-01 /opt/nexus mkdir -p /data/nexus-data chown -R nexus:nexus /opt/nexus-3.12.0-01 /data/nexus-data数据目录的位置通过bin/nexus.vmoptions和etc/nexus-default.properties调整改完之后用bin/nexus run前台启动一次看看日志里输出的数据目录是不是你规划的那个确认之后再改成后台服务方式运行。3.3 首次启动与管理员账号3.12.0 这个版本第一次启动后管理员账号还是传统的默认凭据登录后会强制要求改密码。改成强密码之后立刻做两件事一是把匿名访问的策略确认一遍二是配置一个独立的部署账号给 CI 用。用管理员账号跑 CI 是很多团队的习惯但一旦这个账号的密码轮换所有流水线全挂这个坑完全可以避免。匿名访问这块我的建议是私库里的托管仓库一律不允许匿名写读权限按团队实际情况决定。如果允许匿名读客户端就不用配凭据接入成本低但等于内网的任何人都能下载你的私有包。我们最终选择了对外的 group 开放匿名读、托管仓库本身禁止匿名这个折中方案在便利性和隔离性之间相对平衡。3.4 用 Docker 先搭一套演练环境正式迁移之前我先用容器起了一套临时环境做演练把整个流程跑通一遍确认每一步的耗时和可能失败的位置。这一步的价值在于正式迁移的时间窗口是有限的如果第一次操作就上生产遇到问题只能现场摸索而演练环境里你可以随便重启、随便重来。演练环境要注意的是持久化目录的挂载容器一删数据就没所以数据目录必须挂出来。另外端口映射要跟正式环境保持一致因为后面配置升级代理的连接地址时端口不同会让脚本没法直接复用。演练完之后这套脚本和命令基本可以原样搬到正式环境效率提升非常明显。4. 核心迁移流程升级代理的实际用法4.1 2.11.4 到 2.14.x 的这一跳不能省这是整个迁移里最关键、也最容易让人卡住的一点。官方的升级代理对 Nexus 2 的版本是有下限要求的2.11.4 这个版本太低代理直接连不上或者读不出数据。所以正式迁移的第一步是在旧机器上把 Nexus 2 从 2.11.4 升到 2 系列的末期版本2.14.x 这个区间这一步是原地覆盖式的版本升级相对安全但依然要先做冷备份。做这一跳之前我的建议是把 Nexus 2 的整个数据目录先tar一份到别的盘上然后停服务、替换程序目录、启动。升级完之后重点验证三件事仓库列表是否完整、随机挑几个坐标能不能正常下载、管理界面登录是否正常。三件事都过了再进入下一步。注意Nexus 2 的版本升级只替换程序目录不要动数据目录。把数据目录也一起替换或者覆盖等同于把仓库内容全部清空。4.2 升级代理的部署与连通性检查升级代理是一个独立的小程序部署在与 Nexus 2 网络可达的机器上它负责把 Nexus 2 的数据以标准接口的形式暴露给 Nexus 3。部署逻辑很简单解压、配置指向 Nexus 2 的地址和管理员凭据、启动然后它会监听一个自己的端口默认在 8070 附近具体以你下载版本的说明为准。这里有几个连通性检查必须做。第一从 Nexus 3 所在机器curl升级代理的端口确认能通。第二确认代理配置里填的 Nexus 2 管理员账号确实有读取所有仓库的权限否则迁移会表现为只迁了一部分剩下的没报错但也没数据。第三检查两边的防火墙策略尤其是跨网段的场景端口放行经常漏掉。还有一件事必须提前做冻结 Nexus 2 的写入。迁移过程中如果有新的依赖被 deploy 到旧库这部分数据是不会被同步过去的。最稳妥的做法是临时收回部署权限让 CI 的发布任务失败一段时间等迁移验证完成后再把发布目标切到新库。4.3 在 Nexus 3 里发起迁移并盯日志Nexus 3 侧的操作入口在系统管理里需要先启用迁移相关的能力然后填写升级代理的地址和凭据选择要迁移的仓库点击开始。发起之后不要急着关掉页面进度是通过后台任务跑的页面只是一个观察窗口。真正的观察点在日志里。我会开两个终端一个跟 Nexus 3 的日志一个跟升级代理的日志重点看三类信息单个仓库的迁移是否开始、是否有报错重试、整体进度是否在推进。如果某个仓库长时间没有任何输出基本可以判断是卡住了这时候要有心理准备——官方工具在这个版本上对中断恢复的支持并不理想中途停了通常得重新跑这个仓库。所以我的策略是先迁小的、不重要的仓库确认流程稳定之后再迁大的。第一次迁的就是那个只有几百兆的第三方包仓库整个流程几分钟就走完了验证成功之后才动几十 G 的中央仓库代理。这个顺序看起来浪费时间实际上是把风险控制在自己能承受的范围内。4.4 迁移后的仓库核对清单迁移结束不等于迁移成功。我在 Nexus 3 里按下面这张清单逐项核对每一项都实际点进去看过。核对项检查方法常见异常仓库数量与类型Repositories 页面逐个对照 Nexus 2 的清单代理型仓库被迁成了托管型代理仓库的 remote URL打开仓库配置看远程地址地址为空或指向错误的上游内容条数看仓库的组件数是否与预期量级相符数量只有一小部分说明中途失败group 成员打开 group 配置看成员列表新迁进来的仓库没被加进 group匿名访问权限用不带凭据的请求试拉一个包返回 401快照仓库内容打开几个老快照版本看是否完整同一个版本出现多条重复记录其中 group 成员这一项特别容易被忽略。迁移过来的仓库不会自动加入已有的 group需要你手工在 group 的配置里把它们加进去。我见过有人迁移完之后客户端一直拉不到包排查了半天才发现是 group 里根本没有新仓库。5. 没有升级代理时的兜底方案脚本搬运5.1 用 Nexus 2 的 REST API 拉取清单官方工具搞不定的仓库我准备了一套自己搬的方案。第一步是拿到完整的组件清单。Nexus 2 的接口里可以按仓库列出内容但更省事的做法是直接读磁盘上的目录结构因为 Nexus 2 的存储就是按坐标组织的文件树路径本身就是元数据。SRC/data/nexus/sonatype-work/nexus/storage/releases find $SRC -name *.pom -type f | head -20输出大概长这样org/example/tool/1.2.3/tool-1.2.3.pom。从路径就能反推出坐标最后一段是版本倒数第二段是 artifactId前面的目录层级拼起来就是 groupId。这个规律非常稳定用它写脚本比调接口可靠得多。5.2 用 Nexus 3 组件上传接口回灌Nexus 3 提供了组件上传接口可以按仓库名提交一组文件Maven 格式的上传需要同时带上坐标参数和文件。用脚本按坐标逐组提交是最直接的方式下面是我实际用的一段 Python 骨架思路是把目录里的文件按 artifact 分组再用 multipart 提交。import os, requests NEXUS3 http://new-nexus:8081/service/rest/v1/components AUTH (deployer, password) REPO releases ROOT /data/nexus/sonatype-work/nexus/storage/releases def submit(group, artifact, version, files): data { maven2.groupId: group, maven2.artifactId: artifact, maven2.version: version, } for i, path in enumerate(files, start1): data[fmaven2.asset{i}] (os.path.basename(path), open(path, rb)) r requests.post(NEXUS3, params{repository: REPO}, authAUTH, filesdata) print(group, artifact, version, r.status_code) for dirpath, _, filenames in os.walk(ROOT): poms [f for f in filenames if f.endswith(.pom)] if not poms: continue rel os.path.relpath(dirpath, ROOT) parts rel.split(os.sep) if len(parts) 3: continue group ..join(parts[:-2]) artifact, version parts[-2], parts[-1] files [os.path.join(dirpath, f) for f in filenames] submit(group, artifact, version, files)这里有几个实操细节。路径层级少于三层的目录要跳过那是仓库根目录的元数据文件不是真实组件。每个 artifact 的文件要一次性提交完只传 jar 不传 pom 会在 Nexus 3 里生成一个缺少依赖信息的组件后续别人拉下来照样报错。另外快照的版本号需要做一次还原因为磁盘上是带时间戳的形式要把它变回以-SNAPSHOT结尾的版本号否则 Nexus 3 会把它当成一个正式版本存进去。5.3 用 Maven 自身的 deploy 做小批量搬运接口脚本写起来有点重如果只是零星的几个包用 Maven 自己的部署命令更省事。它能直接把本地的 jar 和 pom 推到你指定的仓库坐标全部通过参数传入不需要写代码。mvn deploy:deploy-file \ -Durlhttp://new-nexus:8081/repository/releases \ -DrepositoryIdnexus3 \ -DgroupIdorg.example -DartifactIdtool -Dversion1.2.3 \ -Dpackagingjar \ -Dfiletool-1.2.3.jar \ -DpomFiletool-1.2.3.pom这个方式的问题是每条命令都要启动一次 JVM几百个包跑下来时间很长而且一旦某个包坐标推错事后很难查。所以我只用它处理那些脚本搬运失败的零星包批量场景还是用接口。提示无论是接口还是 deploy 命令回灌完成后都要去 Nexus 3 里搜一下这个坐标确认能搜到、能下载、pom 里的依赖信息完整。只上传成功不代表组件是可用的。6. 客户端切换settings.xml、CI 与 IDE 的改动点6.1 仓库地址变了镜像配置必须跟着改这是客户端侧最大的变化也是所有构建报错的根源。Nexus 2 的对外地址形如/nexus/content/groups/public/而 Nexus 3 的地址结构变成了/repository/仓库名/中间那段content/groups没有了。老客户端的配置如果不改会在拉取时直接 404而且报错信息往往含糊看不出是地址问题。mirrors mirror idnexus3/id nameinternal nexus3/name urlhttp://new-nexus:8081/repository/maven-public//url mirrorOfcentral/mirrorOf /mirror /mirrors关于mirrorOf的取值我的建议是不要图省事写*。写*会把所有仓库请求都强制走私库包括一些插件仓库一旦私库断掉所有构建全部失败而且排查时很难看出是哪一类请求受影响。只把中央仓库的地址镜像掉其他仓库正常直连或者按需代理稳定性更好。凭据配置放在同一个文件里注意用户名密码要和 Nexus 3 里创建的部署账号一致。密码建议通过环境变量或者外部的凭据文件注入直接明文写在 settings.xml 里然后提交到代码库是很多人踩过的坑。servers server idnexus3/id username${env.NEXUS_USER}/username password${env.NEXUS_PASS}/password /server /servers6.2 Jenkins、GitLab CI 这类流水线的改造点流水线侧的改动比本地开发更需要注意因为它们是批量执行的一个配置错误会影响所有任务。我按这个顺序处理先在流水线里把 Nexus 地址从环境变量或者共享配置中提取出来确认只有一个地方需要改然后在一两个非核心任务上试运行确认无误再全量切换。代理设置也要同步更新。如果流水线跑在没有外网的环境里Maven 的代理参数和私库地址是两套东西改了一个忘了一个表现就是私库能连、插件下载失败。另外Nexus 3 的部署路径也变了原来指向 releases 仓库的上传地址需要改成新的/repository/形式这个如果不改构建本身能成功但最后一步发布依赖会失败。6.3 IDEA 与本地缓存的清理本地的 IDE 是另一个高频出问题的地方。切换私库之后本地已经缓存的依赖元数据还指向老地址表现就是命令行能构建IDEA 里一片爆红。这时候不要急着怀疑配置先把本地仓库里对应 artifact 的元数据清掉再重新拉。rm -rf ~/.m2/repository/org/example mvn -U clean install-U参数强制更新快照和元数据切换私库后的第一次构建建议都加上。如果 IDEA 依然爆红检查一下它的 Maven 配置用的是不是全局的 settings.xml有些项目里会自带一份项目级的配置文件优先级更高容易造成我明明改了全局配置但没生效的困惑。7. 常见问题与排查实录7.1 迁移中断、卡死与重试迁移过程中最常见的问题就是某个仓库卡住不动。判断方法是看日志有没有新的输出如果十分钟以上没有任何进展基本可以确认是卡住了。原因通常有三种仓库里有一个体积异常大的文件、磁盘写入变慢、或者升级代理与 Nexus 2 之间的连接被中间设备掐断。处理上我的建议是不要等直接停掉这次任务的这个仓库把大体积文件单独拎出来手工搬剩下的内容重新跑一次。等待的代价往往比重新跑更大因为迁移窗口的时间是有限的。另外正式迁移之前一定要给磁盘预留足够的写入性能如果用的是网络存储先做一次写入测试再开始。7.2 401 和 403 的排查顺序这两个状态码对应的原因完全不同排查顺序也不一样。401 是没认证通常是客户端没有带凭据或者 Nexus 3 里匿名访问被关掉了但客户端还按匿名的预期在请求。403 是认证过了但没权限多半是部署账号没有被授予对应仓库的写权限或者角色配置漏了某个仓库。排查的时候按这个顺序走先用curl带凭据直接请求一个具体文件确认是不是客户端配置的问题再检查 Nexus 3 里这个账号的角色和权限最后确认这个仓库本身有没有特殊的访问策略。我遇到过一次典型案例账号权限完全正确但因为是往 group 地址上传而 group 本身不允许写入导致一直返回 403。上传必须走托管仓库的地址不能走 group。7.3 校验和、元数据与快照的坑校验和不匹配是回灌过程中最烦人的问题之一。表现是文件传上去了但客户端下载时报校验失败。原因通常是源文件在 Nexus 2 里就已经有问题或者传输过程中断导致文件不完整。处理办法是先对比源文件和目标文件的哈希值确认是哪一端的问题必要时在客户端把校验策略放宽到警告级别但这是临时手段不能长期依赖。快照的问题更隐蔽。Nexus 2 里同一个快照版本每次发布都会生成一份带时间戳的文件迁移到 Nexus 3 之后这些历史文件可能会被识别成多条独立记录结果就是这个快照版本下挂了一堆内容。如果这些历史快照没有保留价值最干净的做法是迁移完成后清理掉让后续的发布重新生成一份。判断是否有价值的标准很简单有没有业务方明确说我需要回滚到某个具体的旧快照没有的话就清。7.4 管理员密码忘掉之后怎么办这是个很高频的问题。3.12.0 这个版本第一次启动有默认的管理员凭据登录后会强制修改。如果改完忘了或者其他同事改过没同步常规做法是停服务、在数据目录里定位到存放安全配置的那部分数据、把它清掉然后重启让系统重建一套默认的安全配置。重启后你会拿到一个新的默认管理员账号。注意这个操作会把用户、角色、权限配置全部重置同时你之前配置的 token 也会失效。它是找回访问权的最后手段做之前务必确认数据目录已经备份并且清楚后续要重建哪些账号和权限。7.5 迁移之后的性能调优记录迁移本身只是第一阶段迁移完之后大量的查询和下载会把新实例压出问题。我在迁移完成后做了三件事。第一调整 JVM 参数按第 2 节那张表的建议值设置堆和直接内存并加上适合大内存的垃圾回收策略。第二把数据目录和日志目录分到不同的物理盘上避免日志写入影响内容读取。第三重建索引。迁移过来的组件在初始状态下搜索性能并不好跑一次索引重建类的任务明显能改善。同时把清理类的计划任务配起来定期清理代理仓库里长期没人访问的缓存内容控制住磁盘增长。这几步做完热数据的响应速度会有肉眼可见的提升。现象可能原因处理方向迁移任务长时间无输出超大文件或磁盘写入瓶颈单独手工搬运该文件重跑仓库客户端 404仓库地址结构没改换成新的 repository 路径客户端 401未带凭据或匿名被关配置凭据或调整匿名策略客户端 403权限不足或往 group 上传补齐角色权限改用托管仓库地址搜索不到已迁移的组件索引未重建触发索引重建任务磁盘快速上涨缓存未清理配置清理类计划任务8. 双轨并行与回滚预案8.1 灰度切换的顺序新旧两套私库并行一段时间是我这次迁移里最满意的一个决定。切换顺序按影响面从小到大排先切我自己的开发机用两三天确认日常构建没有问题再切一两个非核心项目的 CI最后才是核心项目的流水线和全团队。每切一批观察一天再进下一批。这个顺序的意义在于一旦某批出现问题你立刻知道是哪一类使用者受影响而且可以精准地让他们改回旧地址不会影响其他人。如果一上来就全量切换出问题时所有人同时构建失败你连问题出在哪一类客户端上都判断不出来。8.2 回滚到底怎么回回滚这件事要在开始之前就想好而不是出事之后再想。我的做法是整个灰度期内 Nexus 2 保持运行且保持只读所有客户端配置里的旧地址都保留着只是通过流水线的变量控制实际用哪个。这样回滚的操作就是改回一个变量值重启一下任务成本极低。需要接受的一个现实是迁移之后在新库里发布的新版本回滚到旧库是带不回去的。所以灰度期内我要求团队尽量把新版本的发布压后或者接受回滚期间这部分版本需要手工补传到旧库。这个约束在切换前就跟所有人说清楚比出事之后解释要有效得多。我自己做完这套迁移最大的体会是真正花时间的从来不是敲命令而是前期的盘点和后期的验证。工具能帮你搬数据但搬完之后这个仓库是不是完整、这个权限是不是对、这个地址是不是所有人都改了只能靠一条一条核对。另外一个小技巧分享给要动手的人把整个迁移过程写成一份带命令的清单文档每一步后面留一个勾选框迁移当天照着往下走比凭记忆操作可靠得多而且下次再遇到类似的任务这份文档就是现成的操作手册。后续如果要把 npm 或者 docker 仓库也收进同一个实例其实就是在 Nexus 3 里新建对应格式的仓库再配一遍权限迁移的这套思路完全可以复用。
返回列表