
团队协作开发时,你一定遇过这些场景:本地打包半小时还卡在依赖下载,换个网络环境直接拉不到jar包;团队二方库散落在各个开发本地,版本混乱到冲突排查一下午;公共仓库里的恶意jar包混入项目,线上触发安全漏洞被罚;跨团队协作时,依赖包传递全靠U盘拷贝,效率低到离谱。 这些问题的核心解法,就是搭建一套属于团队的Maven私服。
Maven私服的本质,是位于Maven客户端与远程公共仓库之间的私有代理仓库服务,同时也是团队内部二方构件的托管中心。

私服的核心价值覆盖四个核心维度,绝非仅加速下载:
当前行业主流的三款私服方案,各有其适用场景与优劣势,选型核心看团队规模、预算与功能需求。
方案 | 开源协议 | 核心优势 | 局限性 | 适用场景 |
|---|---|---|---|---|
Nexus Repository Manager 3 | OSS版为EPL-1.0开源协议 | 支持Maven、npm、Docker等20+包格式;仓库类型丰富;权限管控粒度细;社区生态完善,文档齐全;企业级特性丰富 | OSS版无原生高可用集群、高级安全扫描功能 | 绝大多数中小企业、互联网团队的首选,从个人开发到大型团队均适用 |
Apache Archiva | Apache 2.0开源协议 | 完全开源免费,Apache基金会维护,轻量,占用资源少 | 仅支持Maven格式,功能单一,社区活跃度低,高级特性缺失 | 个人开发、超小型团队,仅需基础Maven代理功能 |
JFrog Artifactory | 开源版为Apache 2.0,企业版商业收费 | 全语言包格式支持,高可用能力强,DevOps流水线集成度高,高级安全与治理能力强 | 开源版功能受限严重,企业版成本高,学习曲线陡峭 | 大型企业、全栈DevOps体系完善的团队,有充足的预算 |
我接触过近百个团队的私服搭建,90%以上的团队最终都会选择Nexus3 OSS版。它的平衡点做得极好,开源免费版完全能满足中大型团队的核心需求,生态完善,遇到问题很容易找到解决方案,而Archiva功能太单薄,Artifactory开源版的限制太多,商业版成本过高,非超大型团队完全没必要。
基于Sonatype官方规范,Nexus3的运行环境需满足以下基础要求:
容器化部署可彻底解决环境依赖问题,部署流程简单、运维便捷,是当前企业最主流的部署方式。
# CentOS系统安装Docker
yum install -y yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install -y docker-ce docker-ce-cli containerd.io
systemctl start docker
systemctl enable docker
# Ubuntu系统安装Docker
apt update
apt install -y ca-certificates curl gnupg lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update
apt install -y docker-ce docker-ce-cli containerd.io
systemctl start docker
systemctl enable docker
mkdir -p /opt/nexus-data
chown -R 200:200 /opt/nexus-data
官方镜像内的nexus用户UID与GID固定为200,必须完成赋权,否则容器内进程无权限写入挂载目录,导致启动失败。 3. 启动Nexus3容器
docker run -d \
--name nexus3 \
-p 8081:8081 \
-v /opt/nexus-data:/nexus-data \
--restart=always \
-e INSTALL4J_ADD_VM_PARAMS="-Xms4g -Xmx4g -XX:MaxDirectMemorySize=2g" \
sonatype/nexus3:3.70.1-02
JVM参数遵循官方推荐规范,Xms与Xmx设置为相同值,避免堆内存动态调整带来的性能损耗,MaxDirectMemorySize设置为Xmx的50%,满足Nexus的IO操作需求。 4. 启动验证与初始登录
# 查看容器启动日志
docker logs -f nexus3
当日志输出Started Sonatype Nexus OSS 3.70.1-02,说明服务启动成功。 初始管理员密码存储在挂载目录的admin.password文件中,执行以下命令获取:
cat /opt/nexus-data/admin.password
访问http://宿主机IP:8081,使用用户名admin与获取到的初始密码登录,登录后会强制修改管理员密码,同时可配置是否开启匿名访问。团队内网使用场景下,推荐开启匿名读权限,简化依赖拉取配置,上传操作保留认证权限。
针对无Docker环境的场景,可采用二进制包直接部署,步骤如下:
# CentOS系统安装JDK17
yum install -y java-17-openjdk java-17-openjdk-devel
# 验证安装
java -version
# 下载官方二进制包
wget https://download.sonatype.com/nexus/3/nexus-3.70.1-02-unix.tar.gz
# 解压到/opt目录
tar -zxvf nexus-3.70.1-02-unix.tar.gz -C /opt/
解压后生成两个目录:/opt/nexus-3.70.1-02为程序目录,/opt/sonatype-work为数据存储目录。 3. 创建运行用户并赋权
# 创建nexus运行用户
useradd nexus
# 给程序与数据目录赋权
chown -R nexus:nexus /opt/nexus-3.70.1-02 /opt/sonatype-work
/opt/nexus-3.70.1-02/bin/nexus.vmoptions文件,修改为官方推荐配置:-Xms4g
-Xmx4g
-XX:MaxDirectMemorySize=2g
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/opt/sonatype-work/nexus3/heapdump.hprof
/etc/systemd/system/nexus.service服务文件,内容如下:[Unit]
Description=Nexus Repository Manager
After=network.target
[Service]
Type=forking
User=nexus
Group=nexus
ExecStart=/opt/nexus-3.70.1-02/bin/nexus start
ExecStop=/opt/nexus-3.70.1-02/bin/nexus stop
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
# 重载systemd配置
systemctl daemon-reload
# 设置开机自启
systemctl enable nexus
# 启动Nexus服务
systemctl start nexus
# 查看服务运行状态
systemctl status nexus
服务启动成功后,初始密码存储在/opt/sonatype-work/nexus3/admin.password文件中,登录流程与容器化部署一致。
个人开发场景下,可在Windows环境部署Nexus3,步骤如下:
nexus.exe /install安装服务,执行nexus.exe /start启动服务sonatype-work/nexus3/admin.password文件中,访问http://127.0.0.1:8081登录即可。Nexus3针对Maven提供四种核心仓库类型,其中hosted、proxy、group为核心必用类型,virtual虚拟仓库已基本淘汰。 Maven客户端请求私服的完整链路如下:

hosted宿主仓库是私服自身托管的仓库,所有上传的内部二方构件均存储在此类仓库中,不会向公网发起任何请求。 hosted仓库分为两类核心子类型,底层通过版本策略(Version Policy)实现严格管控:
-SNAPSHOT后缀,默认部署策略为Disable redeploy,禁止重复上传同一个版本号的构件,避免正式版本被覆盖,导致团队内依赖不一致。-SNAPSHOT后缀,默认部署策略为Allow redeploy,允许重复上传同一个版本号的构件,每次上传会生成带时间戳的新版本,客户端可通过配置更新策略拉取最新快照包。Nexus3安装后会默认创建maven-releases与maven-snapshots两个宿主仓库,完全符合企业使用规范,无需额外新建,直接使用即可。
proxy代理仓库用于代理远程公共仓库,客户端请求的构件在本地无缓存时,proxy仓库会向配置的远程仓库发起拉取请求,拉取成功后缓存到本地,后续请求直接从本地返回,无需再次访问公网。 proxy代理仓库的核心配置项说明:
企业场景下,推荐配置的代理仓库如下:
https://maven.aliyun.com/repository/public,国内访问速度最快,已代理Maven中央仓库、Spring官方仓库、JBoss仓库等绝大多数常用公共仓库,是首选代理配置。https://repo1.maven.org/maven2/,作为备用代理仓库,应对阿里云仓库同步不及时的场景。无需配置过多代理仓库,过多的仓库会拉长构件查找链路,降低响应速度,阿里云公共仓库已覆盖99%的常用构件场景。
仓库组是Nexus3最核心的设计之一,可将多个hosted、proxy仓库合并为一个虚拟的仓库地址,客户端仅需配置这一个地址,即可访问仓库组内所有子仓库的构件,无需配置多个仓库地址,大幅简化客户端配置。 仓库组的核心规则必须严格遵循:
Repositories菜单。Create repository,选择maven2(proxy)仓库类型。aliyun-public,仓库唯一标识,不可包含空格。https://maven.aliyun.com/repository/public。Mixed。Create repository完成创建。maven-public(类型为maven2(group)),点击编辑按钮。aliyun-public从Available列表移到Members列表中,调整子仓库顺序为:maven-releases、maven-snapshots、aliyun-public、maven-central。Save完成配置,此时maven-public仓库组已整合内部宿主仓库与阿里云代理仓库,可作为客户端唯一配置地址使用。我见过太多团队把仓库组的顺序搞反,将代理仓库放在前列,宿主仓库放在后方,导致每次请求内部二方包,都会先向公网代理仓库发起请求,不仅响应速度慢,还会因公网网络波动导致内部包拉取失败,这个顺序必须严格遵循。
Maven的配置分为两个层级:全局配置settings.xml,位于Maven安装目录的conf文件夹下,对当前机器所有Maven项目生效;项目级配置pom.xml,位于项目根目录,仅对当前项目生效。团队协作场景下,优先推荐统一配置全局settings.xml,避免每个项目重复配置。
以下为完全符合Maven官方规范的完整配置,所有核心标签均有明确的底层逻辑支撑,可直接修改对应地址与账号密码后使用:
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.2.0 https://maven.apache.org/xsd/settings-1.2.0.xsd">
<localRepository>/opt/maven-repository</localRepository>
<pluginGroups>
<pluginGroup>org.apache.maven.plugins</pluginGroup>
</pluginGroups>
<proxies>
</proxies>
<servers>
<server>
<id>maven-releases</id>
<username>admin</username>
<password>你的私服管理员密码</password>
</server>
<server>
<id>maven-snapshots</id>
<username>admin</username>
<password>你的私服管理员密码</password>
</server>
<server>
<id>maven-public</id>
<username>admin</username>
<password>你的私服管理员密码</password>
</server>
</servers>
<mirrors>
<mirror>
<id>nexus-public</id>
<name>Nexus Public Repository Group</name>
<url>http://你的私服IP:8081/repository/maven-public/</url>
<mirrorOf>*</mirrorOf>
</mirror>
</mirrors>
<profiles>
<profile>
<id>nexus-profile</id>
<repositories>
<repository>
<id>maven-public</id>
<url>http://你的私服IP:8081/repository/maven-public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>maven-public</id>
<url>http://你的私服IP:8081/repository/maven-public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>nexus-profile</activeProfile>
</activeProfiles>
</settings>
id必须与后续pom.xml中distributionManagement内的repository id完全一致,包括大小写,Maven采用严格字符串匹配,不一致会导致上传构件时无法找到认证信息,返回401未授权错误,这是90%的用户上传包失败的核心原因。 该配置用于存储私服的认证账号密码,避免在每个项目的pom.xml中暴露账号信息,同时实现全局统一管理。*:匹配所有仓库请求,所有依赖拉取均会转发到私服,是最常用的配置。external:*:匹配所有不在本机与局域网的仓库请求,仅公网请求走私服,适合同时存在内网与公网仓库的场景。*,!repo1:匹配所有仓库,除了id为repo1的仓库,适合特殊仓库不走私服的场景。 需注意:Maven只会使用第一个匹配成功的mirror,后续mirror不会生效,无需配置多个mirror节点。always:每次构建均检查是否有最新快照版本,开发环境推荐使用,确保拉取最新代码。daily:默认值,每天仅检查一次最新版本,当天上传的快照包不会自动拉取,是快照版本不更新的常见原因。interval:X:每隔X分钟检查一次最新版本。never:永远不检查,仅使用本地缓存的版本。pom.xml中核心配置为distributionManagement,用于指定构件上传到私服的目标仓库地址,完整的项目pom.xml示例如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jam.demo</groupId>
<artifactId>demo-common</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>demo-common</name>
<description>Java项目公共组件demo</description>
<url>https://github.com/ken/demo-common</url>
<licenses>
<license>
<name>Apache 2.0 License</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<id>ken</id>
<name>ken</name>
<email>ken@demo.com</email>
</developer>
</developers>
<properties>
<java.version>17</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<lombok.version>1.18.30</lombok.version>
<mybatis-plus.version>3.5.7</mybatis-plus.version>
<spring-boot.version>3.3.5</spring-boot.version>
<springdoc.version>2.6.0</springdoc.version>
<fastjson2.version>2.0.53</fastjson2.version>
<guava.version>33.2.1-jre</guava.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>${springdoc.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>${fastjson2.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.3.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.8.0</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
<doclint>none</doclint>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<distributionManagement>
<repository>
<id>maven-releases</id>
<name>Nexus Release Repository</name>
<url>http://你的私服IP:8081/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>maven-snapshots</id>
<name>Nexus Snapshot Repository</name>
<url>http://你的私服IP:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
</project>
-SNAPSHOT),snapshotRepository对应快照版本(version带-SNAPSHOT),Maven会根据项目的version自动选择对应的仓库上传,无需手动切换。完成上述配置后,执行以下命令即可完成项目的清理、编译、测试、打包与全量上传:
mvn clean deploy
执行成功后,可在Nexus后台对应的仓库中查看到上传的构件。 其他项目如需引用该构件,仅需在pom.xml中添加如下依赖即可,只要settings.xml配置正确,Maven会自动从私服拉取对应构件:
<dependency>
<groupId>com.jam.demo</groupId>
<artifactId>demo-common</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
针对未发布到公共仓库的jar包(如厂商SDK、自定义修改的第三方包),可通过两种方式上传到私服,实现团队内统一共享。
Upload菜单,选择maven-releases仓库(快照版选择maven-snapshots)。Select file to upload,选择本地待上传的jar包。Upload完成上传。mvn deploy:deploy-file \
-Dfile=./demo-sdk.jar \
-DgroupId=com.demo.sdk \
-DartifactId=demo-sdk \
-Dversion=1.0.0 \
-Dpackaging=jar \
-Durl=http://你的私服IP:8081/repository/maven-releases/ \
-DrepositoryId=maven-releases
如需同时上传源码包与javadoc包,可在命令中添加如下参数:
-Dsources=./demo-sdk-sources.jar \
-Djavadoc=./demo-sdk-javadoc.jar
-DrepositoryId必须与settings.xml中对应的server id完全一致,否则会返回401错误。
企业场景下需遵循最小权限原则,不可全员使用admin账号,Nexus基于RBAC(基于角色的访问控制)模型实现权限管理,核心逻辑为:用户 → 角色 → 权限 → 仓库。 企业常用角色配置步骤如下:
Roles菜单,点击Create role。nx-repository-view-maven2-*-browse、nx-repository-view-maven2-*-read,仅具备浏览与读取权限,无法上传与修改。nx-repository-view-maven2-*-add、nx-repository-view-maven2-*-edit,具备构件上传权限。Users菜单,点击Create user,创建对应用户,设置用户名、密码,分配对应的角色。企业场景下,普通开发仅需分配读权限,仅公共组件负责人具备发布权限,从根源避免随意上传构件导致的版本混乱与安全问题。
私服内的构件与配置是团队的核心资产,必须做好备份与容灾处理,同时支持服务器迁移场景。
# 停止Nexus容器
docker stop nexus3
# 打包数据目录,生成带日期的备份包
tar -zcvf nexus-data-backup-$(date +%Y%m%d).tar.gz /opt/nexus-data
# 启动Nexus容器
docker start nexus3
# 将备份包拷贝到异地存储,完成备份
/opt/sonatype-work数据目录,步骤与上述一致。 数据恢复时,只需将备份包解压到对应数据目录,完成权限赋权后启动服务,所有配置、仓库、构件均可完全恢复。mvn dependency:go-offline命令,拉取项目全量依赖,新私服会自动从旧私服拉取所有构件并缓存到本地。企业生产环境必须使用HTTPS访问私服,避免账号密码与构件在传输过程中被窃听或篡改,推荐通过Nginx反向代理实现HTTPS,无需修改Nexus本身的配置。
/etc/nginx/ssl/目录。/etc/nginx/conf.d/nexus.conf,内容如下:server {
listen 443 ssl;
server_name nexus.demo.com;
ssl_certificate /etc/nginx/ssl/nexus.demo.com.crt;
ssl_certificate_key /etc/nginx/ssl/nexus.demo.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
client_max_body_size 1G;
location / {
proxy_pass http://你的私服IP: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_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
server {
listen 80;
server_name nexus.demo.com;
return 301 https://$server_name$request_uri;
}
nginx -t
nginx -s reload
http://你的私服IP:8081替换为https://nexus.demo.com,即可通过HTTPS安全访问私服。 如使用自签名证书,需将证书导入到JDK的信任库中,避免SSL证书不受信任错误,命令如下:keytool -import -alias nexus -keystore $JAVA_HOME/lib/security/cacerts -file ./nexus.crt -storepass changeit
Nexus3 OSS版内置了基于Sonatype OSS Index数据库的漏洞扫描能力,可自动扫描仓库内构件的已知CVE漏洞,配置步骤如下:
Capabilities菜单。Create capability,选择Audit: Vulnerability Detection。Enable,配置需扫描的仓库(默认全量maven2仓库),点击Create完成配置。Browse页面的构件详情中,可查看对应的漏洞信息,包括漏洞等级、CVE编号、修复版本。企业场景下,需定期执行漏洞扫描,针对log4j2、fastjson等高危漏洞,必须及时升级到安全版本,避免线上安全事故。
Maven从发起依赖请求到获取到构件的完整链路,每一步都有明确的规则,理解该链路可快速定位90%的依赖相关问题:
完整的依赖查找链路流程图如下:

maven-metadata.xml是Maven管理版本信息、快照更新的核心元数据文件,绝大多数快照版本不更新、版本号找不到的问题,均与该文件相关。 maven-metadata.xml分为三类:仓库组级元数据、宿主仓库级元数据、代理仓库级元数据,分别管理不同范围的版本信息。 快照版本的maven-metadata.xml完整示例如下:
<?xml version="1.0" encoding="UTF-8"?>
<metadata modelVersion="1.1.0">
<groupId>com.jam.demo</groupId>
<artifactId>demo-common</artifactId>
<version>1.0.0-SNAPSHOT</version>
<versioning>
<snapshot>
<timestamp>20260429.120000</timestamp>
<buildNumber>1</buildNumber>
</snapshot>
<lastUpdated>20260429120000</lastUpdated>
<snapshotVersions>
<snapshotVersion>
<extension>jar</extension>
<value>1.0.0-20260429.120000-1</value>
<updated>20260429120000</updated>
</snapshotVersion>
<snapshotVersion>
<extension>pom</extension>
<value>1.0.0-20260429.120000-1</value>
<updated>20260429120000</updated>
</snapshotVersion>
</snapshotVersions>
</versioning>
</metadata>
核心字段的底层含义:
快照版本的底层更新逻辑:当上传1.0.0-SNAPSHOT版本的构件时,Nexus不会直接覆盖原有文件,而是生成带时间戳与构建号的新版本文件(如1.0.0-20260429.120000-1.jar),同时更新maven-metadata.xml文件,记录最新的快照版本信息。客户端拉取1.0.0-SNAPSHOT版本时,会先请求该元数据文件,解析出最新的快照版本,再拉取对应的构件文件,这就是快照版本可重复上传、实时更新的底层原理。
Maven通过校验和机制保障依赖构件的完整性与安全性,每个jar包、pom文件都会对应生成MD5与SHA1校验和文件,例如demo-common-1.0.0.jar,会同步生成demo-common-1.0.0.jar.md5与demo-common-1.0.0.jar.sha1文件。 校验和机制的完整执行逻辑:
该机制是Maven依赖安全的核心保障,从根源避免恶意构件、损坏构件混入项目。
核心原因:90%的场景是settings.xml中server的id与pom.xml中distributionManagement内的repository id不一致(包括大小写);剩余10%为账号密码错误、用户无对应仓库的上传权限。 解决方案:
核心原因:
-SNAPSHOT后缀的快照版本被上传到releases仓库,releases仓库默认禁止快照版本上传。-SNAPSHOT后缀的版本会自动上传到snapshotRepository,不可手动配置到releases仓库。核心原因:
mvn clean install -U,-U参数强制Maven更新快照版本,不受updatePolicy配置影响。核心原因:
*,匹配所有仓库请求,确保所有依赖均走私服。核心原因:
df -h检查服务器磁盘使用率,清理不必要的文件释放磁盘空间。核心原因:JDK的信任库中未导入私服的SSL证书,自签名证书默认不被JDK信任。 解决方案:
keytool -import -alias nexus -keystore $JAVA_HOME/lib/security/cacerts -file ./nexus.crt -storepass changeit
主版本号.次版本号.修订号,主版本号为不兼容的API变更,次版本号为功能新增,修订号为问题修复,例如1.0.0。-SNAPSHOT,例如1.0.0-SNAPSHOT,开发完成后去除后缀,发布正式版本。