在微服务架构中,搭建一个 Maven 私服(Private Repository 或称为仓库管理器)是非常重要的,它带来了诸多好处:
- 提高构建速度和稳定性: 将外部依赖(如 Maven Central)缓存到本地私服,避免每次构建都去远程下载,加快构建速度,并减少对外部仓库稳定性的依赖。
- 管理内部依赖: 微服务之间可能共享一些公共库、API 定义或父 POM。私服提供了一个中心化的位置来存储和分发这些内部构建的 artifact(构件)。
- 控制和安全: 可以控制团队可以使用的外部依赖版本,实施安全策略,并且内部构件不会暴露到公网。
- 促进 CI/CD: CI/CD 流水线需要一个可靠的地方来获取依赖和发布构建产物。
最常用的 Maven 私服工具是 Sonatype Nexus Repository Manager 和 JFrog Artifactory。这里以 Nexus Repository Manager OSS (免费版) 为例,介绍搭建步骤。
搭建 Nexus Repository Manager OSS 作为 Maven 私服
步骤 1:环境准备
- 服务器: 准备一台服务器(物理机、虚拟机或 Docker 容器)。建议配置至少 4GB 内存和足够的磁盘空间(取决于你的项目规模和依赖数量)。
- Java 环境: Nexus 3.x 需要 Java 8 或更高版本的 JRE。确保服务器上已安装并配置好 JAVA_HOME。
java -version
步骤 2:下载并安装 Nexus
- 下载: 访问 Sonatype Nexus Repository 下载页面:https://www.sonatype.com/products/repository-manager/download
选择最新的 Nexus Repository Manager OSS 3.x 版本(通常是unix.tar.gz
或windows.zip
格式)。 - 解压: 将下载的文件解压到你选择的安装目录,例如
/opt/nexus
或C:\nexus
。
解压后会看到两个目录:# Linux 示例 tar -zxvf nexus-repository-manager-oss-*.tar.gz -C /opt/ # 重命名方便管理 (可选) mv /opt/nexus-repository-manager-oss-*/ /opt/nexus
nexus-<version>
: Nexus 程序目录。sonatype-work
: Nexus 数据目录(仓库、配置、日志等)。
步骤 3:配置 Nexus (可选)
- 端口: 默认端口是
8081
。如果需要修改,编辑<nexus_dir>/etc/nexus-default.properties
文件中的application-port
。 - 数据目录: 默认数据目录在安装目录下的
sonatype-work
。如果想放到其他位置(如独立的数据盘),可以修改<nexus_dir>/bin/nexus.vmoptions
文件中的-Dkaraf.data
和-Djava.io.tmpdir
参数指向新的sonatype-work
路径。 - 运行用户: 出于安全考虑,不建议使用
root
用户运行 Nexus。可以创建一个专门的用户:
然后修改# Linux 示例 sudo useradd -r -m -U -d /opt/nexus -s /bin/false nexus sudo chown -R nexus:nexus /opt/nexus sudo chown -R nexus:nexus /path/to/sonatype-work # 如果数据目录分离
<nexus_dir>/bin/nexus.rc
文件,设置run_as_user="nexus"
。
步骤 4:启动 Nexus
- Linux:
cd /opt/nexus/bin ./nexus start # 其他命令: ./nexus stop, ./nexus restart, ./nexus status
- Windows:
cd C:\nexus\bin nexus.exe /run # 在前台运行,方便看日志 # 或者安装为服务 (需要管理员权限): nexus.exe /install <服务名>, nexus.exe /start <服务名>等
- 查看日志: 启动日志位于
<sonatype-work>/nexus3/log/nexus.log
。观察日志直到看到类似 “Started Sonatype Nexus OSS” 的信息。
步骤 5:初始化设置
- 访问 Web UI: 在浏览器中访问
http://<你的服务器IP>:8081
。 - 获取初始密码: 首次启动时,管理员
admin
的初始密码存储在<sonatype-work>/nexus3/admin.password
文件中。# Linux 示例 cat /path/to/sonatype-work/nexus3/admin.password
- 登录: 点击右上角的 “Sign in”,使用用户名
admin
和上一步获取的初始密码登录。 - 修改密码和设置: 首次登录会强制要求修改管理员密码,并可以选择是否允许匿名访问(建议禁用匿名访问以增强安全性,但根据需要配置)。
步骤 6:配置 Maven 仓库 (核心)
Nexus 默认创建了一些仓库,我们需要理解并配置它们以满足微服务需求:
仓库类型:
- hosted: 托管仓库,用于存储你自己的(内部)构件(Releases 和 Snapshots)。
- proxy: 代理仓库,代理公共的远程仓库(如 Maven Central, JCenter)。当开发者请求构件时,Nexus 先检查本地缓存,如果没有则从远程仓库下载并缓存。
- group: 仓库组,将多个 hosted 和 proxy 仓库聚合为一个逻辑仓库,提供单一的 URL 给开发者和构建工具使用。
默认关键仓库:
- maven-central (proxy): 代理官方 Maven Central 仓库 (
https://repo1.maven.org/maven2/
)。 - maven-releases (hosted): 用于存储你内部发布的 稳定版本 (Release) 构件。
- maven-snapshots (hosted): 用于存储你内部开发的 快照版本 (Snapshot) 构件(例如
1.0.0-SNAPSHOT
)。Snapshot 版本允许覆盖更新。 - maven-public (group): 默认的仓库组,通常聚合了
maven-central
,maven-releases
,maven-snapshots
。这是你应该配置给开发者和 CI/CD 使用的主要 URL。
- maven-central (proxy): 代理官方 Maven Central 仓库 (
检查和配置:
- 登录 Nexus UI,点击左侧导航栏的齿轮图标 (Administration) -> “Repository” -> “Repositories”。
- 检查
maven-central
(proxy): 确认 “Remote storage” 指向正确的 Maven Central URL。可以调整 “Maximum component age” 和 “Maximum metadata age” 来控制缓存策略。 - 检查
maven-releases
(hosted): 确认 “Version policy” 是 “Release”,“Deployment policy” 设置为 “Allow redeploy”(允许覆盖部署,但通常 Release 版本不应被覆盖,根据策略选择 Disable 或 Allow)。 - 检查
maven-snapshots
(hosted): 确认 “Version policy” 是 “Snapshot”,“Deployment policy” 设置为 “Allow redeploy”(Snapshot 版本需要允许覆盖)。 - 检查
maven-public
(group):- 确认它包含了
maven-releases
,maven-snapshots
,maven-central
(可能还有其他你需要的代理仓库,如 JBoss, Google 等)。 - 调整顺序: 成员仓库的顺序很重要,Nexus 会按顺序查找构件。通常把 hosted 仓库(
releases
,snapshots
)放在前面,proxy 仓库(central
)放在后面。 - 获取 URL: 点击
maven-public
仓库,复制其 URL,例如http://<你的服务器IP>:8081/repository/maven-public/
。这个 URL 将用于配置 Maven 客户端。
- 确认它包含了
步骤 7:配置 Maven 客户端 (开发者和 CI/CD 环境)
修改 Maven 的 settings.xml
文件(通常位于 ~/.m2/settings.xml
或 Maven 安装目录的 conf/settings.xml
),使其指向你的 Nexus 私服。
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<!-- (可选) 本地仓库路径 -->
<!-- <localRepository>/path/to/local/repo</localRepository> -->
<pluginGroups>
<!-- (可选) Maven 插件组 -->
</pluginGroups>
<proxies>
<!-- (可选) 如果需要通过 HTTP 代理访问 Nexus -->
</proxies>
<servers>
<!-- 配置访问 Nexus hosted 仓库所需的认证信息 (用于 deploy) -->
<server>
<id>nexus-releases</id> <!-- 这个 ID 需要与 pom.xml 中 distributionManagement 的 repository ID 匹配 -->
<username>your-deploy-user</username> <!-- 建议在 Nexus 中创建专门的部署用户 -->
<password>your-deploy-password</password>
</server>
<server>
<id>nexus-snapshots</id> <!-- 这个 ID 需要与 pom.xml 中 distributionManagement 的 snapshotRepository ID 匹配 -->
<username>your-deploy-user</username>
<password>your-deploy-password</password>
</server>
</servers>
<mirrors>
<!-- 配置镜像,将所有 Maven 请求重定向到你的 Nexus 公共组 -->
<mirror>
<!-- 这里的 id 可以自定义,例如 'nexus-mirror' -->
<id>nexus-public-mirror</id>
<!--
mirrorOf 配置为 '*', 表示拦截所有仓库请求(除了 localhost 和基于文件的仓库)。
也可以配置为 'central' 只拦截中央仓库,或者 'external:*' 拦截所有远程仓库请求。
推荐使用 '*' 或 'external:*' 以确保所有依赖都通过私服。
-->
<mirrorOf>*</mirrorOf>
<!-- 指向你的 Nexus 公共仓库组 URL -->
<url>http://<你的服务器IP>:8081/repository/maven-public/</url>
</mirror>
</mirrors>
<profiles>
<!--
如果不想使用 mirror (例如只想代理 central),
可以在 profile 中配置 repository 指向 nexus-public。
但 mirror 通常更简单直接。
-->
<!--
<profile>
<id>nexus-profile</id>
<repositories>
<repository>
<id>nexus-public</id>
<url>http://<你的服务器IP>:8081/repository/maven-public/</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>nexus-public</pluginRepository>
<url>http://<你的服务器IP>:8081/repository/maven-public/</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
-->
</profiles>
<!--
<activeProfiles>
<activeProfile>nexus-profile</activeProfile>
</activeProfiles>
-->
</settings>
关键配置解释:
<servers>
: 配置访问需要认证的仓库(主要是部署时访问maven-releases
和maven-snapshots
)的用户名和密码。id
必须与后面pom.xml
里distributionManagement
中定义的repository
或snapshotRepository
的id
完全一致。建议在 Nexus 中创建专门的部署用户和角色,而不是使用 admin。<mirrors>
: 使用<mirror>
元素将 Maven 的仓库请求重定向到你的maven-public
仓库组。mirrorOf
设为*
或external:*
是最常用的方式,强制所有外部依赖都通过私服。<profiles>
(替代 Mirror): 如果不使用 Mirror,可以通过 Profile 定义repository
和pluginRepository
指向maven-public
,并激活该 Profile。Mirror 通常更简单。
步骤 8:配置项目 POM 文件以进行部署
在需要发布到私服的微服务项目(尤其是共享库、API 包、父 POM)的 pom.xml
文件中,添加 <distributionManagement>
部分:
<project>
...
<distributionManagement>
<repository>
<!-- 这个 ID 必须与 settings.xml 中 server 的 ID 匹配 -->
<id>nexus-releases</id>
<name>Nexus Releases Repository</name>
<!-- 指向你的 Nexus Releases 仓库 URL -->
<url>http://<你的服务器IP>:8081/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<!-- 这个 ID 必须与 settings.xml 中 server 的 ID 匹配 -->
<id>nexus-snapshots</id>
<name>Nexus Snapshots Repository</name>
<!-- 指向你的 Nexus Snapshots 仓库 URL -->
<url>http://<你的服务器IP>:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
...
</project>
步骤 9:使用
- 拉取依赖: 开发者或 CI/CD 服务器执行
mvn clean install
,mvn package
等命令时,Maven 会通过settings.xml
配置的 Mirror/Profile 访问 Nexus 的maven-public
组来下载所有依赖。如果 Nexus 本地没有,它会从上游(如 Maven Central)下载并缓存。 - 发布构件: 对于配置了
distributionManagement
的项目,执行mvn deploy
命令会将构建产物(JAR, WAR, POM 等)发布到 Nexus 的maven-releases
(如果版本号是 Release) 或maven-snapshots
(如果版本号是 SNAPSHOT) 仓库。这需要settings.xml
中配置了正确的server
认证信息。
最佳实践和考虑:
- 备份: 定期备份 Nexus 的数据目录 (
sonatype-work
) 非常重要。 - 安全: 使用 HTTPS 访问 Nexus UI 和仓库 URL;配置强密码;创建不同权限的角色和用户(如部署用户、只读用户)。
- 清理策略: 配置 Nexus 的清理策略(Cleanup Policies),自动删除旧的 Snapshot 版本和不使用的 Release 版本,防止磁盘空间耗尽。
- 高可用: 对于大型或关键生产环境,可以考虑 Nexus Pro 版本的 HA(高可用)集群方案。
- 容器化: 使用 Docker 部署 Nexus 是一个非常流行和方便的方式,可以简化安装和管理。官方提供了 Docker 镜像。