尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Maven私服搭建指南:Nexus仓库配置与依赖管理最佳实践

Maven私服搭建指南:Nexus仓库配置与依赖管理最佳实践 1. 为什么要自建 Maven 私服先搞清楚我们到底在解决什么问题1.1 Maven 跑了这么多年为什么还需要一个私服Maven 作为 Java 生态里最主流的构建工具日常开发基本离不开它。很多初学者最开始接触 Maven 的时候只知道一件事在pom.xml里写上依赖坐标然后mvn install或者让 IDE 自动解析依赖就哗哗地下载下来了。这背后其实是 Maven 默认去访问中央仓库Maven Central拉取 jar 包整个链路看起来简单但真到了团队协作和公司内部项目阶段问题就开始冒出来了。我接触过的不少团队都经历过这样的场景新同事入职第一天拉下代码后mvn compile等了二十多分钟一半时间卡在下载依赖上下午两点中央仓库某个依赖的某个版本出了问题全组人的构建集体挂掉公司内部封装的公共组件比如基础工具包、日志封装、统一的 Redis 客户端只能靠mvn install装到本地仓库换个电脑就全没了。这些问题的根源只有一个所有机器都直接连外网 Maven 中央仓库没有任何中间层。私服的价值恰恰就在这里——它充当了一个“本地中央仓库”的角色把外部仓库的依赖缓存到内网同时收纳公司内部的构建产物。如果你从来没搭过私服我可以负责任地说在你还没遇到上述任何一个问题之前搭建它代价是最小的。等团队膨胀到十人以上再去处理你就得忍受两个星期的阵痛期。1.2 Nexus 能做什么从仓库代理到团队协作中心私服工具目前主流的有两家Apache Archiva、Sonatype Nexus。如果让我推荐毫无疑问是 Nexus而且直接用 Nexus 3.x不要选 2.x2.x 已经很少见到新部署了。Nexus 3 除了支持 Maven还支持 npm、Docker、PyPI、NuGet 等格式也就是说公司的前端依赖、Python 包都能统一管理一个工具打通所有语言生态。具体到 Maven 场景Nexus 的核心职责可以拆成三块。第一块是代理外部仓库。你不需要让每台开发机都直连 Maven 中央仓库而是让 Nexus 去连接中央仓库把下载过的依赖缓存到本地磁盘。第一个同事下载了spring-coreNexus 把 jar 存下来第二个同事再要同一个依赖时直接从 Nexus 本地缓存返回速度飞快即使外网抖动也不影响。第二块是托管内部构件。团队内部发布的公共组件部署到 Nexus 的 hosted 仓库里其他项目直接通过坐标引用。这替代了“人人本地 install、靠微信群传 jar 包”的原始状态版本变更、依赖追溯都有据可查。第三块是仓库统一入口。通过 Nexus 的 group 仓库把多个仓库内部 hosted 仓库 外部代理仓库合并成一个地址暴露给开发机开发者的settings.xml里只需要配置一个仓库地址不需要关心背后到底有几个物理仓库。我要特别强调一个点私服不是搭起来就完事的它是一个需要持续维护的基础设施。你规划得好它就是团队构建效率的助推器你规划得稀烂它就是另一个到处飘着报错的“大坑”。后面几节我会从安装、配置到维护完整走一遍。2. 环境准备与 Nexus 安装从零开始部署第一个实例2.1 环境选型与下载准备先说我建议的部署环境。Nexus 3 是基于 JVM 的应用官方支持 Linux、Windows、macOS但生产环境最好放在 Linux 服务器上。配置上做了一个简单的对比大家可以参考场景建议配置说明个人试用/学习2 核 4G 内存、50G 磁盘够跑别开太多仓库团队规模 10~30 人4 核 8G 内存、200G SSD基本无压力大型团队/跨部门8 核 16G 内存、500G SSD考虑单独挂数据盘内存是硬指标Nexus 本体 JVM 堆内存 操作系统缓存4G 的机器给 Nexus 用刚刚好低于 2G 的话启动会比较吃力也可能出现莫名的卡顿。下载地址可以去 Sonatype 官网help.sonatype.com/repomanager3找最新版也可以走 GitHub releases直接下载nexus-3.x.x-xx-unix.tar.gz这个 Linux 版本压缩包。这里提醒一句选版本的时候别盲目追新选一个已经发布超过半年的稳定版本更靠谱新版本踩坑概率相对高一些。Java 环境方面Nexus 3.30 以上版本要求 JDK 8 及以上新版本甚至要求 JDK 11。安装包自带了 Jetty 作为 Web 服务器所以不需要你再配置 Tomcat。我当时因为机器上只有 JDK 8还特意多注意了一下版本兼容问题最终在.bashrc里指定了不用全局 JDK 变量。2.2 安装与启动Linux 下的完整操作流程下面是我在 CentOS 7/8 和 Ubuntu 上部署时都比较稳的一套流程直接照做基本就能起来。第一步创建专用用户。这个细节很多人忽略但我强烈建议不要直接用 root 跑 Nexus。创建系统用户nexus把数据目录和安装目录的所有者都给它好处是即使 Web 管理后台被攻破也只是普通用户权限不会被直接提权到 root。useradd -r -m -s /bin/bash nexus第二步解压安装包并调整目录结构。Nexus 的压缩包解压后会有两个目录nexus-3.x.x-xx程序目录和sonatype-work数据目录。建议把这两个目录都放到/opt/nexus/下面方便统一管理mkdir -p /opt/nexus tar -zxvf nexus-3.x.x-xx-unix.tar.gz -C /opt/nexus/ mv /opt/nexus/nexus-3.x.x-xx /opt/nexus/nexus mv /opt/nexus/sonatype-work /opt/nexus/sonatype-work chown -R nexus:nexus /opt/nexus第三步修改启动配置。需要改两个文件。第一个是/opt/nexus/nexus/bin/nexus.vmoptions这里设置 JVM 参数。默认的-Xms2703M -Xmx2703M对内存要求有点高如果是 4G 内存的机器建议改成-Xms1024M -Xmx1024M -XX:MaxDirectMemorySize2G第二个是/opt/nexus/nexus/bin/nexus脚本里的run_as_user配置默认是#run_as_user改成run_as_usernexus第四步启动服务。切换到nexus用户启动su - nexus /opt/nexus/nexus/bin/nexus start启动过程需要一点时间可以通过日志查看进度tail -f /opt/nexus/nexus/log/nexus.log看到类似Started Sonatype Nexus OSS的日志就代表启动成功了。然后访问http://服务器IP:8081能打开 Nexus 的 Web 界面就说明第一步完成。Windows 上其实也差不多唯一区别是解压后用cmd进入bin目录运行nexus.exe /run或者安装成 Windows 服务。但开发机不建议长期跑 Nexus毕竟占资源公司局域网里一台 Linux 服务器或者 NAS 跑它就够了。2.3 初始化配置改端口、改密码、设置数据目录Nexus 默认端口是 8081如果和你别的服务冲突可以在nexus-default.properties文件里改vi /opt/nexus/nexus/etc/nexus-default.properties重点改这三个键application-host0.0.0.0 application-port8082 nexus-args${jetty.etc}/jetty.xml,${jetty.etc}/jetty-http.xml,${jetty.etc}/jetty-requestlog.xmlapplication-host建议显式配置为0.0.0.0这样局域网内其他机器才能访问。改完重启生效。第一次登录的时候Nexus 默认管理员账号是admin初始密码在数据目录下的admin.password文件里。你需要先 cat 一下这个文件拿到初始密码第一次登录后系统会强制要求重置密码。这一步很多人会卡住——网上搜到的默认密码是admin123但 Nexus 3 新版本早就不是这个了。正确姿势是cat /opt/nexus/sonatype-work/nexus3/admin.password执行这条命令后输出的内容就是本次初始密码登录后按提示改成你自己的密码。如果以后忘了密码也可以通过重置这个文件的方式来找回我会在第 7 节详细讲。数据目录sonatype-work是 Nexus 存储所有仓库、索引、配置的地方非常重要。有条件的话建议把它挂载到独立的磁盘分区或者网络存储上避免系统盘故障连带丢数据。我自己的做法是直接把整个/opt/nexus/sonatype-work做了一次软链接到/data/nexus-data后续备份也好做。3. 仓库类型与仓库组Nexus 的核心概念一次讲透3.1 三种仓库类型Proxy、Hosted、Group熟悉 Nexus 之后你会发现搞懂三类仓库就懂了一半。Nexus 的仓库类型设计得非常清晰理解它们之后目录规划就不是什么难事。Proxy代理仓库本身不存内部代码只作为外部 Maven 仓库的“缓存代理”。比如我配置一个代理仓库指向 Maven Central开发者请求一个依赖时Nexus 先去本地缓存找找不到再向中央仓库发起远程请求把结果缓存下来。这个代理仓库还承担了一个非常实用的功能——屏蔽远程仓库的间歇性故障。哪怕中央仓库短暂宕机只要之前有缓存团队构建不受影响。Hosted宿主仓库这才是“属于你的仓库”用来承载公司内部的构建产物。内部公共组件、二方库都部署到这里不同团队之间共享。Nexus 默认已经创建了三个 hosted 仓库maven-releases发布版本、maven-snapshots快照版本、maven-central代理中央仓库。实际使用过程中你可以根据团队成员规模和应用场景再新增一些自定义 hosted 仓库比如独立的第三方授权仓库专门存那些无法从中央仓库获得的商业 jar 包。Group仓库组可以把多个 proxy 和 hosted 仓库合并成单个逻辑地址。开发者的settings.xml只配置这一个 group 地址就相当于同时具备了“访问外部中央仓库”和“拉取内部组件”的能力。为什么需要它因为 Maven 在一个仓库找不到依赖时并不会自动去另一个仓库找而 group 仓库替你做了一层聚合和路由省了配置多个 mirror 的麻烦。3.2 仓库组Repository Group的合并逻辑仓库组的工作方式有点像路由器你请求group仓库下的任意一个依赖Nexus 会按照组内成员列表的顺序依次查找第一个找到的就返回。我强烈建议组的成员顺序为hosted 仓库内部库在前proxy 仓库外部代理在后。原因很简单内部依赖优先级高先查内部库能避免外部依赖覆盖内部同名组件的风险。比如公司内部开发了com.company:common-utils:1.0.0如果外部中央仓库恰好也有同名同版本的坐标顺序错了就会拉到外部版本造成不可控的问题。默认的maven-public组已经包含了maven-releases、maven-snapshots和maven-central顺序也基本合理。你在创建代理仓库时记得也把它加进这个组里否则开发者无法通过默认入口访问新代理的仓库。3.3 创建自己的仓库规划先说说默认仓库的布局。Nexus 3 安装完成后默认有这些仓库仓库名类型说明maven-centralproxy代理 Maven Centralmaven-releaseshosted内部正式发布版本maven-snapshotshosted内部快照版本maven-publicgroup默认聚合仓库我个人习惯再加两个仓库一个是maven-aliyun代理仓库指向阿里云的公共 Maven 镜像另一个是third-party托管仓库专门存放商业授权或无法从公共仓库获取的第三方 jar。然后在maven-public组里加入这两个新仓库。代理仓库创建时有一个重要参数叫Remote Storage。默认填的中央仓库地址是https://repo1.maven.org/maven2/国内网络访问这个地址经常很慢所以我一般直接改成阿里云镜像地址https://maven.aliyun.com/repository/public这样 Nexus 从远程拉取依赖时走的就已经是阿里云的加速链路开发机的下载速度会明显提升。当然如果你在公司内网有更快的内部镜像源也可以填内部地址。4. Maven 配置settings.xml 才是整个私服方案的灵魂4.1 settings.xml 核心配置项Nexus 装好了、仓库也规划好了接下来就是要让每一台开发机的 Maven 知道私服的存在这一步要靠settings.xml完成。它位于 Maven 安装目录的conf/目录下用户级别的配置则在~/.m2/settings.xml。两者的区别是全局settings.xml影响所有用户用户级settings.xml只影响当前用户实践中我会让每个开发者在自己的~/.m2/settings.xml里配置避免权限问题。settings.xml里最重要的四个区域是localRepository本地仓库位置。默认是~/.m2/repository如果磁盘空间紧张可以改到其他盘。mirrors镜像配置。这里负责把中央仓库的请求重定向到私服地址。servers服务器认证信息。只有当你要从私服下载私有依赖或向私服发布部署时需要在这里配置访问私服的账号密码。profiles仓库配置。配合activeProfiles可以指定 Maven 处理依赖时用哪个仓库作为默认仓库。一个简单的误区是很多人以为配置了 mirror 就不用配置 profiles/repository 了。其实两者是配合使用的mirror 把所有对repo.maven.apache.org等公共仓库的请求都拦截到私服而 profiles 里的repositories则用于判断依赖是否来自私服的某个具体仓库。如果只配 mirror 不配 profiles某些插件或者 parent pom 的解析可能会因为仓库信息缺失而报错。4.2 配置镜像仓库与单一入口下面给一个我可直接复用的推荐配置。假设 Nexus 的 group 仓库地址是http://192.168.10.10:8081/repository/maven-public/那么全局镜像配置如下settings mirrors mirror idnexus/id nameNexus Repository Manager/name urlhttp://192.168.10.10:8081/repository/maven-public//url mirrorOf*/mirrorOf /mirror /mirrors /settings注意mirrorOf的取值。*表示所有仓库请求都走私服external:*表示只代理外部仓库本地文件系统仓库file://协议的不走镜像如果需要排除某些仓库可以用!repoId,*的格式。如果只是让中央仓库走私服mirrorOfcentral/mirrorOf就够了。但团队内部项目比较多的情况下我建议直接用*让所有请求统一走私服由 Nexus 去分发路由开发者的环境彻底统一。这个方案还有个好处你后续新增代理仓库时不用再跑到每台开发机上去改settings.xml只需要在 Nexus 的 group 仓库里加一个成员即可所有开发机自动生效。4.3 配置 deploy 权限认证如果只是下载依赖配置 mirror 就够了。但要往私服上传内部组件就要用到servers配置了。这里有个非常常见的坑你直接在pom.xml里的distributionManagement写上了私服地址执行mvn deploy时却提示 401 Unauthorized原因就是 Maven 不知道用什么账号去访问私服。这个账号密码必须写在settings.xml里的servers节点并且id要和pom.xml里的仓库 ID 完全一致。以一个内部项目为例它的pom.xml配置了发布地址distributionManagement repository idnexus-releases/id urlhttp://192.168.10.10:8081/repository/maven-releases//url /repository snapshotRepository idnexus-snapshots/id urlhttp://192.168.10.10:8081/repository/maven-snapshots//url /snapshotRepository /distributionManagement那settings.xml里必须写settings servers server idnexus-releases/id usernameadmin/username password你的密码/password /server server idnexus-snapshots/id usernameadmin/username password你的密码/password /server /servers /settings注意两个文件的id必须一致否则 Maven 找不到对应的认证信息。这一点我见过太多人踩坑有些人会把id写成“maven-releases”有人会写成完整的仓库 URL都对不上最后 deploy 永远失败。另外实际生产环境中不建议直接给开发者使用admin账号正确的做法是在 Nexus 的访问控制里创建专用账号比如deployer只授权nx-repository-view-maven2-*-add和nx-repository-view-maven2-*-edit权限。权限控制这部分我在第 8 节详细展开。4.4 设置本地仓库最后别忘了一个细节本地仓库配置。默认所有 jar 包都存在~/.m2/repository这也是大部分教程的默认行为。但如果你平时开发项目非常多、依赖体量很大~/.m2/repository会飞速膨胀。我就是因为 C 盘吃紧把本地仓库挪到了 D 盘在settings.xml的顶层节点加上localRepositoryD:/m2/repository/localRepository然后所有 IDE 的 Maven 配置里也同步指向这个目录。改完之后之前下载的缓存不会自动搬过去需要重新依赖解析。如果你不希望重新下载直接把旧目录内容复制到新目录也可以。5. 部署依赖到私服团队协作的关键一步5.1 distributionManagement 与 mvn deploy前面的配置做好了之后部署一个内部组件到私服只需要三步在项目的pom.xml里配置distributionManagement在开发机settings.xml里写入对应的服务器认证命令行执行mvn clean deploy。deploy阶段做的事情是构建项目、打包、把 jar 和 pom 文件上传到配置的仓库地址。相比install只装到本地仓库deploy会真正把产物推送到远程私服。这里我要特别强调一下版本号规范。部署到maven-releases仓库的版本号不能以-SNAPSHOT结尾而且已经上传过的同版本不能重复覆盖默认策略禁止重复发布。部署到maven-snapshots仓库的版本号则必须包含-SNAPSHOT并且允许覆盖更新。实际开发中我们的协作节奏是这样的开发阶段统一用1.0.0-SNAPSHOT版本所有人都从私服拉取这个快照版本更新频繁不受限制等团队确认版本稳定通过 Maven Release Plugin 或者手动改版本号发布1.0.0正式版正式版一旦发布就锁死不允许随意覆盖。这能够有效避免“同事本地一 install全组都跟着崩”的情况。5.2 Snapshot 和 Release 的版本策略再深入聊一下 Snapshot 和 Release 的区别因为这个理解不彻底后面很容易出问题。Snapshot快照版本哪怕坐标一样内容也是可变的。Maven 默认的策略是如果你配置了快照更新策略每次构建时去远程仓库检查一次快照是否更新如果更新了就重新拉取。开发阶段用快照版本很方便改完代码直接deploy使用方重新构建就能拉到最新版本不需要一直改版本号。缺点是快照版本容易产生“隐式漂移”——上午拉到的代码和下午拉到的代码可能不是同一个状态因此快照版本绝对不能用在生产发布构建上。Release正式版本是不可变的。同一个版本号你只能发布一次第二次相同版本号的部署会被 Nexus 拒绝默认策略是Release仓库开启Disable redeploy。这保证了正式版本的数据完整性也让依赖方可以放心缓存。所以版本管理的铁律是开发阶段用 SNAPSHOT发布阶段用 RELEASE生产构建锁定 RELEASE 版本绝不依赖 SNAPSHOT。5.3 手动上传第三方 JAR有些 jar 是商业授权或者从中央仓库下载不到的比如某些银行提供的加密 SDK、特定型号硬件的驱动。Nexus 的 Web 界面支持手动上传操作路径是Components → Upload Component选择要上传的仓库比如third-party填写 GAV 坐标GroupId、ArtifactId、Version选择上传的 jar 文件如果有对应的 pom 或者源码包也可以一并上传点击上传完成。这种方式适合一次性导入少量文件。但如果你有批量迁移的需求每次都手动点界面效率太低。我自己处理过几十个商业 jar 包的导入用的是 maven 的deploy:deploy-file命令mvn deploy:deploy-file \ -DgroupIdcom.company.thirdparty \ -DartifactIdsdk-encrypt \ -Dversion1.2.3 \ -Dpackagingjar \ -Dfilesdk-encrypt-1.2.3.jar \ -DpomFilesdk-encrypt-1.2.3.pom \ -DrepositoryIdnexus-releases \ -Durlhttp://192.168.10.10:8081/repository/third-party/这里-DrepositoryId必须和settings.xml中的server的id对应也就是前面说过的认证匹配逻辑。批量执行时我一般写一个 shell 脚本循环处理效率会高很多。6. 与 IDE 集成IDEA 配置全流程6.1 IDEA 绑定 Maven 与 settings.xml服务端和命令行都稳了之后接下来要解决的是开发机 IDE 的配置问题。目前主流 IDE 还是 IntelliJ IDEA我以 IDEA 为例讲配置流程Eclipse 的思路类似但具体菜单不同。打开 IDEA进入File → Settings → Build, Execution, Deployment → Build Tools → Maven重点看三个设置项Maven home path这里要选择你本机安装的 Maven 目录。注意 IDEA 自带了一个 Maven如果你没有单独安装 Maven默认会使用自带版本但这样会和你命令行用的 Maven 版本不一致建议统一。User settings file选择~/.m2/settings.xml可以勾选 Override 后填上自定义路径。这一步决定 IDEA 解析依赖时用哪个配置文件。Local repository如果settings.xml里已经配置了localRepositoryIDEA 会自动读取不需要重复设置。没生效的话手动指定一次。配置完成后在 IDEA 右侧的 Maven 面板里点击刷新按钮Reimport All Maven ProjectsIDEA 就会重新解析所有依赖。如果你新配置了私服首次解析时会有一个明显的依赖下载过程耐心等待即可。我见过很多人配置完私服后 IDEA 依然“报红”大部分原因是 IDEA 的 Maven 设置与命令行不是同一个 Maven 版本或者User settings file没有指向你修改过的settings.xml。很多人在命令行用mvn命令能通过IDEA 里却不行请先检查这两个地方。6.2 常见 IDEA 配置问题我来梳理几个我在实际工作中反复遇到的 IDEA 相关问题。问题一IDEA 提示 “Cannot resolve xxx:xxx:1.0.0”依赖解析失败。首先确认该依赖是否真实存在于私服对应仓库然后看 IDEA 的 Maven 设置是否指向了正确 settings.xml最后执行mvn -U clean compile强制刷新快照。如果还不行大概率是版本号或仓库地址不匹配去 Nexus Web 界面搜索确认。问题二IDEA 正常启动但 Maven 面板里一片报红这种通常是本地仓库锁文件或者损坏缓存导致。处理方法是删除~/.m2/repository下对应的_remote.repositories缓存或者彻底关掉重新导入。更稳妥的做法是File → Invalidate Caches / Restart让 IDEA 清掉内部缓存后重新加载。问题三IDEA 的 Maven 日志级别太低看不到报错细节IntelliJ 默认只显示简短错误。你可以在 Maven 面板的 Runner 设置里加上-e错误栈甚至-X调试级别临时开启看完整日志。调试完建议调回来因为-X会打出海量日志影响构建速度。这些问题都不难但都是日常高频场景我把它们写在前面你遇到时能少花很多时间在排查上。7. 常见问题与排查实录我自己掉过的坑7.1 问题速查表先给一个我总结的速查表覆盖我过去几年使用 Nexus 遇到的主要问题后面再挑几个典型的展开说。症状可能原因排查思路页面打不开服务没启动 / 端口被占用 / 防火墙拦截日志看启动状态netstat 查端口firewalld/iptables 放行 8081依赖下载超时代理仓库 remote 地址网络不可达测试 Nexus 服务器到远程仓库的连通性换国内镜像401 Unauthorizedsettings.xml 的 server id 与 pom.xml 仓库 id 不一致或密码错误核对所有 id 和账号密码403 Forbidden当前账号没有写权限 / 仓库禁止重复发布检查权限配置和仓库 Deployment policy400 Bad Request仓库类型不匹配往 proxy 仓库上传确认上传目标是否为 hosted 仓库磁盘写满快照和日志无限增长清理旧快照、配置保留策略构建报 “UnknownHostException”DNS 解析不了远程仓库域名检查服务器 DNS 配置deploy 后远程没有 jardeploy 目标是 snapshot 库但版本非 SNAPSHOT或 distributionManagement 配置错误检查发布日志和仓库里的实际结构7.2 密码忘记了怎么办密码忘记是几乎每个用过 Nexus 的人都经历过的痛。不过 Nexus 3 的密码找回其实不复杂核心思路是重置 admin 用户。操作流程如下停掉 Nexus 服务/opt/nexus/nexus/bin/nexus stop。进入数据目录备份现有的用户配置cp /opt/nexus/sonatype-work/nexus3/etc/users.xml /opt/nexus/sonatype-work/nexus3/etc/users.xml.bak。编辑users.xml找到用户名为admin的用户把password字段改成$shiro1$SHA-512$1024$NEwqQq/TmjZMvfI7ENPCQ$V4yPw8T64UQ6GfJfxYq2hLsVtLpGOxwuu6PLW8DAR2JGW9E4S0C8wZ5xZxK2pVJf3zVfNv4uyEzR6n2WKcL8Gw这一段是预先算好的默认密码哈希对应明文admin123也可以直接清空password字段。重启 Nexus用admin / admin123登录登录时系统会要求重置密码。如果因为版本原因导致哈希值不兼容有一个更通用的做法删除admin用户的加密字段然后前往sonatype-work/nexus3/目录下寻找admin.password相关文件。部分版本中删掉用户密码字段后重启系统会重新生成初始密码文件用这个临时密码登录即可。这个方法也适用于恢复一个完全锁死的实例。但注意修改users.xml之前必须停服务否则会被覆写回去改了个寂寞。7.3 无法下载依赖的排查思路遇到“依赖下载不下来”不要慌按顺序排。先确认 Nexus 能不能连通外网仓库。在 Nexus 服务器上直接执行curl -I https://repo1.maven.org/maven2/如果这条命令超时说明服务器本身无法访问中央仓库这时候配置阿里云代理或者公司其他代理源是首要任务。Nexus 的 proxy 仓库我们一般可以设置多个候选中央仓库选阿里云另一个代理仓库选默认的中央仓库两者都放进 group 组里这样既保证了速度也保留了兜底。再确认具体依赖是否真的在远程仓库里存在。有时你写的坐标没有错误但这个 artifact 并不在中央仓库Nexus 会返回 404。在 Nexus Web 界面用Search功能搜索一下坐标能直观地看到是否存在以及它缓存在哪个仓库。最后确认是不是缓存策略出了问题。Nexus 代理仓库对于远程仓库的响应是有缓存的默认情况下Cache开启Negative Cache是把 404 响应也缓存一段时间。如果某个依赖之前获取失败被缓存了 30 分钟即使远程已经恢复也会继续返回 404。处理办法是在 Nexus 的 proxy 仓库设置中把这个负缓存的 TTL 调短或者在维护窗口直接清空缓存。7.4 磁盘占用与清理Nexus 运行时间长之后磁盘占用会非常可观。大头有三个代理仓库的 blob 缓存、快照仓库的历史版本、以及运行日志。代理仓库缓存不需要手动清理因为它是按需重新拉取的Nexus 提供了自动删除策略。在仓库的Admin → Cleanup Policies里可以配置保留天数和正则表达式匹配的删除规则建议对maven-central和maven-aliyun这两个代理仓库设置“超过 90 天未使用”自动清理。快照仓库的清理逻辑有一个概念叫Remove released versions from snapshot repository开启后如果某个快照版本已经对应发布了正式版本Nexus 会自动移除该快照。这个策略很实用避免快照仓库无限膨胀。日志方面/opt/nexus/nexus/log/和sonatype-work下的日志文件需要定期轮转nexus 自带的 logback 配置默认就会按大小切割但老日志保留策略建议自己查看确认。在低配服务器上这很关键——日志文件能吃掉几十 G 磁盘你敢信我踩过一次磁盘满了之后 Nexus 直接进入只读模式所有 deploy 都失败排查了老半天。8. 安全加固与日常维护8.1 访问控制与账号分配安全这件事很多人搭私服时根本没考虑过等出了问题再补救就很被动了。实际上私服向内网开放并不是什么高风险系统但至少不能什么都不做只留一个 admin 裸奔。我的做法是至少创建三类账号角色账号示例权限管理员admin全部权限发布者deployer对 maven-releases/snapshots 有 add/edit/browse 权限只读用户developer只对 maven-public 有 browse/read 权限操作位置在Security → Users → Create local user角色可以在Security → Roles里定制。最省事的方案是直接把已有的nx-repository-view-maven2-*系列内置权限组件组合成自定义角色避免自己手写一堆规则。给开发者的机器配置私服地址时要特别注意mirror的账号密码是明文写在settings.xml里的如果局域网环境不安全泄露账号密码的风险需要提前评估。我的处理方案是maven-public仓库设置为允许匿名读取开发机不需要额外配置账号就能拉取依赖只有deploy时才使用带认证的账号。这样既便捷又缩小了密码暴露面。8.2 备份与恢复备份的重要性不用我多说。Nexus 3 的数据全在sonatype-work/nexus3里备份思路有两种冷备份停服务打包整个数据目录。优点是简单粗暴、恢复完整缺点是有停机时间。热备份不停服务直接执行打包命令。虽然一致性不是 100% 保证但对绝大多数情况已经够用。我的习惯是每天凌晨用 crontab 执行增量同步把sonatype-work/nexus3/blobs和etc同步到备份服务器rsync -avz /opt/nexus/sonatype-work/nexus3/ backup-server:/data/backup/nexus/一定要至少保留最近 7 天的备份。恢复相对简单把备份目录覆盖回去再启动服务就行Nexus 的 blob 存储记录在索引里的关联关系很可靠基本不需要额外修复。8.3 定期执行的维护事项最后总结一份我建议的维护清单按周期性执行每天检查 Nexus 是否存活看看磁盘剩余空间观察日志有没有大面积异常每周查看快照仓库增长情况处理构建失败告警清理过期快照每月审查代理仓库的磁盘占用调整清理策略检查 Nexus 是否需要升级小版本每季度做一次完整的备份恢复演练确保备份不是“躺在那里的一堆文件”而是真正能恢复的。这些维护动作没有一个是复杂的但都极其关键。很多团队搭好私服就撒手不管半年后再看Nexus 已经成了一台“存储黑洞”连谁在什么时候上传了什么依赖都说不清了。维持一个干净、稳定的内部仓库才是一个合格的私服管理员该做的事。9. 最后分享几个让我收益很大的配置细节搭建 Nexus 这件事本身不难真正值钱的是那些让整个系统稳定运行的小细节。我从自己项目里挑三个特别想推荐的操作给大家参考。第一个是开启 Nexus 的Blob Store 分离。安装完成后默认所有仓库的数据都在同一个 blob store 里项目一多查某个仓库占多大磁盘就很麻烦。我习惯在Repository → Blob Stores里给 maven-releases、maven-snapshots、proxy 缓存分别建不同的 blob store磁盘占用一目了然后续做清理也不用担心误删。第二个是善用 Nexus 的Scheduled Tasks。在 Web 界面的System → Scheduled Tasks可以创建定时任务我目前跑了两个一个每天凌晨清理 30 天前未使用的代理缓存另一个每周做快照仓库的 compact 操作。配好后基本不用管Nexus 自动把仓库维护掉。第三个是Maven 命令加-U和-o的区别要分清楚。日常开发用mvn clean install没问题但如果你刚改完一个内部组件的代码并 deploy 上去想要在别的项目里立即生效需要强制刷新快照这时候用mvn clean install -U。如果断网或者网络状态很差又不想等待仓库超时反而要加-o强制离线模式用本地缓存构建。这个细节用好了会明显改善日常构建体验。我自己的团队从最初“每人直连中央仓库、偶尔自动挂掉”的状态过渡到现在“全量依赖走 Nexus、构建时间缩短一半”的状态中间还经历了不少试错。如果你也准备在团队里推行私服不要把搭建过程想成“装个软件而已”建议先规划仓库目录、账号体系、版本规范再动手部署。一次性把基础打好后面可以省掉很多头疼时刻。
返回列表