☰
Nexus 3.15.2搭建Maven私服全程实践与坑点排查
2026/10/10 18:04:11 网站建设 项目流程

简介:Nexus 3.15.2的Windows 64位官方安装包,定位是在局域网内搭建Maven私服,面向需要集中管理依赖、加快构建速度的Java开发团队和运维人员。通过部署该私服,开发人员连接内网地址即可访问远端Maven仓库,缓存常用构件并统一项目依赖版本,降低外网波动和重复下载的影响。资源以rar压缩包形式提供,整体大小约149.78MB,内含Nexus服务端程序、默认配置及基础文件,解压后即可作为私服环境使用;由于上传方未提供明细,暂不展示内部逐文件清单,但核心用途明确,不影响实际安装部署。当前已有145人学习/下载,适合在Windows环境搭建Nexus私服、希望快速获得可用基础包的技术读者;拿到该包后,可在内网建立统一构件仓库,并在此基础上规划仓库分组、权限控制和代理策略,提升团队研发协作效率。

1. 为什么我还在用 nexus-3.15.2 这个老版本搭 Maven 私服

如果你在一个网络受限的内网环境里做 Java 后端开发,迟早会被一件事逼疯:明明 pom.xml 里写好了依赖,mvn compile 卡在下载插件半小时不动。这时候,一个本地的 Maven 私服就是刚需。但我的选择可能和大多数教程不一样——我没有追最新的 Nexus 4.x,而是翻出了 nexus-3.15.2-win64.rar 这个压缩包继续用。原因很简单:这个版本足够稳定,资源占用比新版低一个量级,而且 3.15.2 的界面逻辑、仓库配置方式完全够用,不需要为了「新」去承担迁移成本。这篇文章就把我从解压到配置、再到踩坑的完整过程拆给你看,新手照着做就能把私服跑起来,熟手可以直接跳到第 4 章和第 5 章看边界参数。

2. 部署 nexus-3.15.2-win64:从压缩包到后台服务

2.1 环境要求与安装前的三个决定

Nexus 3.15.2 是基于 JVM 的应用,win64 包意味着你要在 64 位 Windows 上运行它。别急着双击 exe,先确认三件事。

第一,JDK 版本。3.15.2 官方要求 JDK 8,我不建议用更高版本。实测在 JDK 11 上启动能起来,但有些 Bundle 插件会报类加载异常,你不想在排查环境问题上浪费时间,就装 JDK 8u202 或更早的版本。记住是 64 位 JDK,32 位会直接报「找不到 JVM DLL」。

第二,内存规划。nexus-3.15.2 默认的堆内存设置在 bin/nexus.vmoptions 里,默认 -Xmx1024m。如果你的机器只有 2G 内存,这个值要降;如果私服要供 20 人以上团队使用,建议给 2G 以上。我一般先用默认值跑通,再根据实际压力调整。

第三,端口占用。Nexus 默认端口是 8081 和 8082,前者是 Web 管理界面,后者是 Docker 仓库预留的 HTTPS 端口。这两个端口在 Windows 上经常被其他服务占掉,安装前先执行netstat -ano | findstr :8081看一眼。如果被占,后面统一改。

这三个决定做完,解压就是纯粹的复制操作。我把 nexus-3.15.2-win64.rar 解压到D:\dev\nexus-3.15.2-win64,注意路径不要有中文和空格,Nexus 对带空格的路径处理有问题,启动脚本会找不到变量。

2.2 解压、启动与初始化配置

解压后你会看到两个目录:nexus-3.15.2和sonatype-work。前者是程序本体,后者是数据目录,存放所有仓库的 blob、索引和配置。这个分离很重要,备份时只打包 sonatype-work 就够了。

启动服务有两种方式,我推荐用命令行前台启动先做验证:

cd D:\dev\nexus-3.15.2-win64\nexus-3.15.2\bin nexus.exe /run

参数/run会让 Nexus 在前台运行,日志直接打到当前窗口。这时你能实时看到启动过程。第一次启动会比较慢,因为要初始化数据库和索引,我遇到过在机械硬盘上花了三分钟才看到Started Sonatype Nexus OSS这行日志。

看到启动成功的日志后,打开浏览器访问http://localhost:8081。页面上会让你设置 admin 用户密码,这里有个细节:3.15.2 不像后来的版本会自动生成随机 admin 密码,而是让你在首次访问时手动设。但如果你用nexus.exe /install安装成了 Windows 服务,第一次访问会要求你先去sonatype-work/nexus3/admin.password这个文件里读取初始密码。这是很多新手翻车的地方:

# 以管理员身份运行 CMD,安装为 Windows 服务 nexus.exe /install nexus.exe /start

安装成服务后,控制台不再输出日志,都写到sonatype-work/nexus3/log/nexus.log。如果你没注意 admin.password 文件,就去这个日志里找初始密码相关的提示。

初始化配置中最关键的一步是改访问端口。在管理界面的 Settings -> System -> HTTP/HTTPS 里,可以修改 HTTP 端口。但这里有个坑:修改后 Nexus 会要求重启,而且重启后如果你用的是/run前台方式,Ctrl+C 停掉再重新执行即可。如果是 Windows 服务,用nexus.exe /restart。

Nexus 默认是不允许外部直接访问管理界面的,只监听 localhost?不,3.15.2 默认监听0.0.0.0:8081,所以同一局域网的人可以直接通过你的 IP 访问。如果你只打算本机用,把执行参数改成nexus.exe /run --host 127.0.0.1限制访问来源。

到这里,一个最小可用的私服已经起来了,接下来才是真正干活的仓库配置。

3. 配置 Maven 私服的核心仓库:代理、宿主与组仓库

3.1 三种仓库类型怎么选

刚装好的 Nexus 会自动创建一组内置仓库:maven-central、maven-releases、maven-snapshots、maven-public。很多初学者直接拿maven-public当唯一仓库用,转发所有请求,什么都能拉到。但这违背了私服设计的初衷。

Nexus 仓库分三种类型,功能完全不同:

类型作用典型仓库
proxy代理远程仓库,缓存下载的构件maven-central
hosted本机存储,你上传自己的构件maven-releases, maven-snapshots
group把多个仓库聚合成一个 URL 对外提供服务maven-public

理解它们的区别,你才能设计出合理的仓库组。代理仓库负责对外拉取,宿主仓库负责接收你mvn deploy上传的私有构件,组仓库只是门面。

我的习惯是保留 maven-central 代理仓库,但不会直接用它。因为 maven-central 默认目标是https://repo1.maven.org/maven2/,如果你在中国大陆网络环境下拉取比较慢。我一般新建一个代理仓库,指向阿里云 Maven 镜像:

3.2 用 Nexus 内置仓库还是自建仓库

Nexus 3.15.2 内置的maven-central可以直接用,但有两个原因让我倾向自建代理仓库。

第一,内置仓库的配置是「只读」逻辑,不能调整连接超时和重试次数。当中央仓库响应慢时,Nexus 会卡住下载线程。第二,我需要把代理仓库的Auto blocking改为手动,这样当中央仓库连续失败后,Nexus 不会自动把仓库标记为 offline,导致后续请求直接失败。这个自动屏蔽特性是 3.x 引入的,初衷是减少等待,但在不稳定网络下反而误伤。

所以我的方案是新建一个代理仓库,名字就叫aliyun-maven:

# 通过 REST API 创建代理仓库,也可以界面操作 curl -u admin:你的密码 -X POST http://localhost:8081/service/rest/v1/repositories/maven/proxy \ -H "Content-Type: application/json" \ -d '{ "name": "aliyun-maven", "online": true, "storage": { "blobStoreName": "default", "strictContentTypeValidation": true }, "proxy": { "remoteUrl": "https://maven.aliyun.com/repository/public", "contentMaxAge": 1440, "metadataMaxAge": 1440 }, "negativeCache": { "enabled": true, "timeToLive": 60 }, "maven": { "versionPolicy": "RELEASE", "layoutPolicy": "STRICT" } }'

参数说明:contentMaxAge是缓存构件的时间,单位分钟,1440 就是一天内中央仓库同一路径的更新不会触发重新下载。metadataMaxAge是 maven-metadata.xml 的缓存时间,这个文件用于解决版本范围依赖,设短一点,比如 30 分钟,不然新发布的版本要等很久才能在另外一个客户端解析到。negativeCache的timeToLive是当中央仓库返回 404 时的缓存时间,单位秒,这里设为 60 秒,避免频繁请求不存在的构件。

注意版本策略:我上面写的是"RELEASE",意味着代理仓库只缓存正式版。如果你还要代理快照版本的第三方依赖(比如 Spring 的 profile snapshot),需要改成"MIXED"并把layoutPolicy改为"PERMISSIVE",Nexus 才能识别带时间戳的快照文件名。

创建完代理仓库后,还需要把它加入组仓库maven-public。在界面的 Settings -> Repositories 里点开 maven-public,把aliyun-maven从左边移到右边,保存即可。这样你的私服对外的 URL 还是http://localhost:8081/repository/maven-public/,但实际会先查阿里云。

3.3 配置 settings.xml 与 pom 发布

客户端这边,你要改 Maven 的conf/settings.xml。核心是 mirror 配置,让所有请求都走私服:

<mirror> <id>nexus</id> <mirrorOf>*</mirrorOf> <name>Nexus Mirror</name> <url>http://你的IP:8081/repository/maven-public/</url> </mirror>

mirrorOf写*表示拦截所有远程仓库请求,包括 Maven Central 和插件仓库。如果你只想拦截中央仓库,可以写central。但实际建议用*,因为私服组仓库本身会处理代理关系。注意,这个 mirror 会让本来指向其他仓库的请求全部转到私服,好处是统一管理,坏处是如果私服挂了,你本地所有依赖下载失败。这也是私服的高可用问题。

上传私服构件时,在项目的 pom.xml 中配置 distributionManagement:

<distributionManagement> <repository> <id>nexus-releases</id> <url>http://你的IP:8081/repository/maven-releases/</url> </repository> <snapshotRepository> <id>nexus-snapshots</id> <url>http://你的IP:8081/repository/maven-snapshots/</url> </snapshotRepository> </distributionManagement>

然后执行mvn deploy上传。这里常见问题是在 pom 中声明的版本号带了-SNAPSHOT,Nexus 会把项目路由到快照仓库。如果你在 release 仓库里传了快照版本,Debian 拒绝。所以把maven-releases的 Deployment policy 设为Disable redeploy,防止扩展版本被覆盖。

client 的 settings.xml 里还要配置 server 认证,否则 deploy 返回 401:

<server> <id>nexus-releases</id> <username>admin</username> <password>你的密码</password> </server>

这里 id 必须和 pom.xml 中的 repository id 一致,Maven 才不会报找不到 server 配置。

4. nexus 私服踩坑排查:端口、权限与存储的五个实际问题

4.1 端口被占用导致服务起不来

现象:执行nexus.exe /run后,日志滚动到一半,窗口最后一行只有Interrupted,再访问 8081 无响应。查看日志文件sonatype-work/nexus3/log/nexus.log,里面写着BindException: Address already in use: bind。

原因:另一个程序占用了 8081。Windows 上常见的是 Oracle 的 HTTP 服务或者某些监控软件。

解决:先确认占用进程,再改端口。用管理员 CMD 执行:

netstat -ano | findstr :8081 taskkill /PID 那个进程 /F

如果不想杀进程,就改 Nexus 端口:编辑nexus-3.15.2/etc/nexus-default.properties,将application-port=8081改成 8083。改完重启服务,同时记得把客户端 settings.xml 里的镜像 URL 同步改过来。这个坑经常出现在团队内,你改了端口不发公告,别人还访问 8081 就是一片 502。

4.2 上传构件返回 401 或 403

现象:mvn deploy执行到上传阶段报401 Unauthorized或403 Forbidden,错误信息是Failed to transfer file: Return code is: 401。

原因:大多数情况是settings.xml中 server 节点的id与 pom 中distributionManagement的仓库id不一致。Maven 根据 id 匹配认证信息。另一个常见原因是密码里有特殊字符,比如#、/,而你没做 XML 转义。

解决:先检查 id 匹配,再看密码。我在pom.xml里写的仓库 id 一直习惯叫internal-releases,但 settings.xml 里用的是nexus-releases,导致认不到。统一改成一致的。对于密码,建议你先用 Nexus 界面创建一个只读用户(比如deployer),给它授予nx-repository-view-maven2-*-browse和nx-repository-view-maven2-*-add权限,用这个用户上传。这样避免把 admin 密码写在团队成员本地的 settings.xml 里,权限也好控制。

4.3 内网下载大包超时或中断

现象:多设备同时从私服拉一个 200M 的依赖包,部分请求超时;或者单包下载到一半连接被重置。

原因:Nexus 3.15.2 默认的 Jetty 线程池比较保守,对并发下载有压力;同时代理仓库从中央源拉取大文件时,Nexus 的 HTTP 超时设置默认为 20 秒,当外网源响应慢时,连接提前断开。

解决:调大代理仓库的超时参数。在 Nexus 管理界面,打开你的代理仓库,修改Proxy选项卡里的Connection timeout为 60000,Retries改为 5。注意:这个设置影响的是 Nexus 访问远程仓库的行为,不直接影响客户端。客户端那边需要检查 Maven 的MAVEN_OPTS:

set MAVEN_OPTS=-Dhttp.socketTimeout=600000 -Dhttp.connectionTimeout=60000 mvn clean install

另外,作为补救,可以用 Maven 的-o离线模式直接在本地仓库寻找依赖,如果你确认本地仓库有该构件,离线模式能绕过网络问题。但不要让团队形成本地复制仓库的坏习惯,否则私服的缓存意义就没了。

4.4 磁盘占用爆炸式增长

现象:运行一个月后,sonatype-work目录占了 80G,打开 Nexus 界面看到仓库列表前有黄色感叹号,日志提示Blob store is full。

原因:Nexus 3.x 默认使用 MarkLogic Blob 存储,每个文件一个 blob,且保留历史版本。如果你从不清理,中央代理仓库的缓存会无限膨胀。尤其是当客户端请求了多次-SNAPSHOT版本时,Nexus 会不断缓存新的时间戳快照。

解决:给仓库配上清理策略。3.15.2 虽然是老版本,但已经支持 Cleanup Policies。在 Settings -> Repositories 选择你要清理的仓库,点击Cleanup,创建策略:

# 典型策略:保留 30 天内访问过的构件,其他全删除 Name: release-cleanup Criteria: - Last blobby updated: 30 days - Release version type: RELEASE

这里Last blobby updated不是文件最后修改时间,而是那个 blob 在 Nexus blob store 中最后被访问的时间。如果你想让「30 天没人下载的旧版本自动删除」,选这个。Last downloaded是从远程源下载的时间,意义不大。清理策略比较保守,配合Compact blob store任务才能真正释放磁盘空间:创建任务Admin - Compact blob store,选择 default blob store,即刻执行。我建议写一个计划任务,每周日凌晨跑一次 compact。

还有一个最容易犯的错:把代理仓库的contentMaxAge设为 0。这样做没有好处。它会让 Nexus 每次都去远程源重新拉取,不仅慢,而且每次拉取都会产生新 blob,旧 blob 没失效,磁盘增长更快。正常设置 1440 即可。

4.5 依赖验签失败:证书时间问题

现象:Maven 下载依赖时报invalid signature for file,即使来源是可信的。

原因:这是时间同步问题。Nexus 或者客户端机器的时间与真实时间偏差过大,导致 Maven 校验 HTTPS 证书或校验带签名构件时,验证失败。Windows 机器最常见的是主板电池没电,时间慢了几分钟,而 Maven 对时间差的容忍度很低。

解决:在 Nexus 所在机器和所有开发机上安装 NTP 时间同步:

w32tm /config /manualpeerlist:"ntp.aliyun.com,0x1" /syncfromflags:manual /reliable:YES /update w32tm /resync

执行后重启 Nexus。这个坑比较隐蔽,很多人以为是授权问题,浪费时间重签密钥,其实只是时间偏了。从那以后,我每次搭建私服后的第一件事,就是把所有涉及机器的 NTP 强制配置一遍,并写进交接文档。

5. 进阶:用 Nginx 反代 Nexus 并启用 HTTPS 的验证方法

5.1 反代配置

Nexus 3.15.2 原生支持 HTTPS,直接配置证书并不难。但现实中我更习惯在前面挂一个 Nginx,因为团队里往往还有其他前端服务,统一通过 Nginx 路由。而且 Nginx 能缓存部分静态文件,减少 Nexus 压力。

在 Nginx 里新建一个 server 块:

server { listen 80; server_name maven.example.com; return 301 https://$host$request_uri; } server { listen 443 ssl; server_name maven.example.com; ssl_certificate /etc/nginx/ssl/maven.crt; ssl_certificate_key /etc/nginx/ssl/maven.key; ssl_protocols TLSv1.2 TLSv1.3; location / { proxy_pass http://127.0.0.1:8081; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_connect_timeout 60s; proxy_read_timeout 600s; proxy_send_timeout 600s; client_max_body_size 500m; } }

参数说下:proxy_read_timeout必须设置足够长,否则客户端下载大构件时,Nginx 在默认 60 秒后会断开。client_max_body_size是允许上传的构件大小限制,我设为 500M,适用于上传大型 fat jar。proxy_set_header Host $host是关键,Nexus 会根据 Host 头生成资源链接,如果你不传 Host,Nexus 可能生成http://127.0.0.1:8081/...这样的内部地址,导致外部访问资源 404。

5.2 验证和日常检查

配置完成后,先本机验证 Nginx 配置语法:

nginx -t

然后重新加载 Nginx。接着用一个真实的 Maven 项目测试,去掉--no-transfer-progress,观察启动下载是否正常:

mvn help:system

如果看到Downloading from nexus: https://maven.example.com/repository/maven-public/...,说明反代已生效。此时再打开 Nexus 管理界面,确认Administration -> System -> HTTP里的Base URL已经设置为https://maven.example.com,否则 Nexus 生成的邮件链接和仓库链接仍指向内网地址。

日常维护时,我最常用的检查命令是:

curl -I https://maven.example.com/repository/maven-public/

如果返回 401,那是正常的,说明 Nexus 在要求认证;如果返回 502,说明 Nexus 没起来或者端口不对。再配合看 Nginx 错误日志和 Nexus 日志,基本能定位九成问题。

还有一个技巧是开一个临时 user-agent 验证反代是否透传正确:

curl -A "maven" https://maven.example.com/repository/maven-public/

Nexus 对 Maven 请求和浏览器请求有着细微的响应差异,如果你在浏览器里能打开 Nexus 页面但 Maven 始终下载失败,大多数是请求头里缺少User-Agent或Host被改写。这时抓包看发出去的请求,和正常 Maven 客户端做对比,别在仓库配置里瞎猜。

把这些配置固化到团队 wiki 后,我已经很少再碰之前那些坑了。但每次给新机器搭私服,我还是会强制走一遍第 4 章里的五个检查点:端口、认证、超时、磁盘、时间。最近一次迁移私服时,就是因为没检查 NTP,硬生生让十个人在旧服务器上多等了一天。希望这篇笔记能帮你少走这段弯路。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询