使用Nexus搭建Maven私服
在实际的企业开发中经常会遇到的问题:在进行 Maven 项目开发时,所需要的构件都是通过 Maven 的中央仓库或者第三方的 Maven 仓库下载到本地,那么企业内部开发使用也会遇到一些问题,团队内的每个使用者都需要去下载相应的依赖包或者插件,效率低下,浪费带宽,网速慢,你可能需要花很长的时间来下载所需的 jar,工作效率低,影响项目进度。并且若存在模块之间的依赖开发,那么 snapshot 版本是不能够被团队伙伴很方便的获取,即:不利于公共构件的管理和维护。另外在实际开发过程中,有些第三方的 jar 包版本可能在中央仓库里面不存在,或者更新不及时,则获取不到这个 jar 包。那这些实际问题需要如何解决呢? 解决方案:搭建企业内部的 Maven 私服。 优点:
1> 私服仓库是本地的,下载的速度远高于从远程下载。
2> 可自行进行构件的管理和维护,包括第三方构件以及项目模块中所依赖的自助开发的公共构件。具体流程如下图 1 所示:
图 1
在上图中,搭建私服后,所有的依赖从私服下载,私服会自动判定,若私服库里没有所需的资源,则私服会自动去远程中央仓库下载,若私服已包含所需资源,则可以通过内网提供给使用者,大大提高工作效率。 下面将根据解决方案,学习如何搭建 Maven 私服。
1.1 Sonatype Nexus
我们使用专门的 Maven 仓库管理软件来完成私服的搭建,比如:Apache Archiva,
Artifactory,Sonatype Nexus。下面我们重点介绍如何使用 Sonatype Nexus 进行私服搭建。
Nexus 是一个非常强大的 Maven 仓库管理器,极大地简化了自己内部仓库的维护和外部仓库的访问。利用 Nexus 就可以只在一个地方就能够完全控制访问和部署在所维护仓库中的每个 Artifact。并且它不需要数据库,它使用文件系统加 Lucene 来组织数据。最大的一个功能就是通过项目的 SNAPSHOT 版本管理,来进行模块间的高效依赖开发。官网:
http://www.sonatype.org/nexus/。注意:Nexus 专业版是需要付费的,这里我们下载开源版
Nexus OSS。
Nexus 提供两种安装包:(下载地址:http://www.sonatype.org/nexus/go)
1> 内嵌 Jetty 容器的 bundle 包(只需有 JRE 就可直接运行)
2> war 包(须将其发布到 Web 容器中即可使用)
补充说明:提供所有版本的下载列表(http://www.sonatype.org/nexus/archived/),可选
择不同版本,这里建议不使用 3.x 的版本,因为无法更新索引,建议使用的 2.x 的版本。
1.2 Maven 私服搭建
1.2.1 安装配置 Nexus 环境
1. 安装环境准备
1> 服务器环境
a) Ubuntu16 64 位
b) JDK 1.8
2> nexus-2.12.0-01-bundle.tar.gz
2. 安装配置
1> 解压 tar
tar -zxvf nexus-2.12.0-01-bundle.tar.gz
2> 配置文件:conf/nexus.properties
3. 开放 8081 端口
apt-get install iptables(安装防火墙)
iptables -I INPUT -p tcp --dport 8081 -j ACCEPT(只对指定的端口进行放行)
iptables-save(保存修改)
apt-get install iptables-persistent(安装)
netfilter-persistent save(保存)
netfilter-persistent reload (重新加载)
4. 启动 Nexus
命令:./usr/local/nexus2.12/nexus-2.12.0-01/bin/nexus start 注意:配置 bin/nexus (RUN_AS_USER=root)
5. 访问 Nexus
http://192.168.248.136:8081/nexus/
默认端口:8081 默认用户名/密码:admin/admin123
1.2.2 Nexus 仓库的设置
因为新搭建的 Neuxs 环境只是一个空的仓库,那么首先就需要与远程中心库进行同步,进行私有仓库索引更新。更新的方式有两种:自动方式、手动方式。
1. 自动更新方式
开启远程索引自动更新下载(Central Repository),设置 Download Remote Indexes: True(远程下载 Central 仓库的索引)。Nexus 会自动从远程中央仓库下载索引文件, 在 Central 上右键点击 Update/Rapair Index,下载 index 文件。一般远程仓库都比较大,构件较多,索引文件会很大,比如:从 http://repo1.maven.org/maven2 下载后 就有 2G,因此需要的时间就比较长。可以进入 Scheduled Tasks 查看任务的执行情况,当执行完成时,远程仓库的索引就已经建立完毕了。更新完索引后可在 Browse Index 页签点击刷新按钮就可显示所有更新后的索引。那么在这里由于网络原因,我们不推荐自动方式,强烈推荐手动方式。
2. 手动更新方式
1> 下载索引文件
➢ nexus-maven-repository-index.gz 下载地址:http://repo.maven.apache.org/maven2/.index/
➢ nexus-maven-repository-index.properties 下载地址:http://repo.maven.apache.org/maven2/.index/
➢ indexer-cli-5.1.0.jar
下载地址:http://maven.outofmemory.cn/org.apache.maven.indexer/indexer-cli/5.1.0/
2> 解压缩索引文件
将上面三个文件(.gz & .properties & .jar)放置到同一目录下,运行命令:
java -jar indexer-cli-5.1.0.jar -u nexus-maven-repository-index.gz -d indexer
3> 停止 Nexus
./usr/local/nexus2.12/nexus-2.12.0-01/bin/nexus stop
4> 删除原有的索引文件
将{nexus_home}\sonatype-work\nexus\indexer\central-ctx 下的文件全部删掉,
执行命令:rm *
5> 拷贝索引至 central-ctx目录下 将 nexus-maven-repository-index.gz 解压后的 indexer 目录中所有文件,放到 sonatype-work\nexus\indexer\central-ctx 下面,执行命令:
cp -r * /usr/local/nexus2.12/sonatype-work/nexus/indexer/central-ctx/
6> 启动 Nexus即自动更新索引 更新完索引后可在 Browse Index 页签点击刷新按钮就可显示所有更新后的索引,展开索引树,点击到叶子节点--依赖 jar 包,可查看其依赖配置坐标。
1.2.3 Nexus 仓库及常规操作介绍
1.2.3.1 Nexus 仓库
Nexus 的 Repositories,一共默认有 8 个仓库,如下图 2 所示:
图 2
上图中 Nexus 的预定义仓库的 type 类型、policy 策略、格式均不同,下面依次进行介绍。
✓ 四种仓库类型:
1> Hosted Repository:本地仓库,通常我们会部署自己的构件到这一类型的仓库。比如公司的一些构件库等等。简单理解就是:内部项目的发布仓库(如:执行 mvn clean install 命令发布项目,最终发布的 jar 包会放入 Hosted Repository)
2> Proxy Repository:代理仓库,它们被用来代理远程的公共仓库,如 Maven 中央仓库。从远程中央仓库中寻找数据的仓库(可以点击对应的仓库的 Configuration 页签下
Remote Storage Location 属性的值即被代理的远程仓库的路径)
3> Virtual Repository:虚拟仓库
4> Repository Group:仓库组,用来合并多个 hosted/proxy 仓库。组仓库用来方便开发
人员进行设置的仓库, group 仓库可以自由组合其他的仓库为一个组,然后在项目的 pom 文件的 repository 可以配置这个仓库。可以说仓库组是为了简化仓库的引用而提出的。
✓ 两种仓库格式:
1> maven2
2> maven1
✓ 两种仓库 Policy:
1> Release(发布版本,即稳定版本)
2> Snapshot(资源快照,版本相对不稳定) 下面我们再重点介绍几个 Nexus 预定义仓库:
1> 3rd party
存放第三方构件,一些无法从公共仓库获得的构件,比如一些早期开源项目,没有采用 Maven 方式构建的,还有一些非开源的组建等等,这些构件中央仓库里没有,需要用户手动上传的构件,那么都会存放在这个仓库里。在仓库的 Artifact Upload 页签中可以执行上传操作。
2> Apache Snapshots: 使用代理 Apache Maven 仓库快照版本的构件仓库
3> Central: 用来代理 Maven 中央仓库中发布版本构件的仓库,策略为 Release、只会下
载和缓存中央仓库中的发布版本构件。 注意:该库是私服上的中央仓库,并不是 Maven 的中央库。可以把常用的 jar 包拷进去,这样客户端就可以从这里下载了。也可作为 Maven 中央库的代理。
4> Releases: 存放稳定版本的构件。比如:我们完成了一个版本下的组件开发,就可以把它发布到这里
5> Snapshots: 存放快照版本的构件。 比如:在下一个组件版本的所有开发和测试工作完成之前,是不应该发布到 release 仓库的,但可能其他项目只需用到这个组件的某些接口,只要这些接口完成了开发并通过测试,就可以拿来使用, 从而实现多个项目并行开发。
6> PublicRepositories: 仓库组
如下图 3 所示,Configuration 里面,Ordered Group Repositories,包含了三个仓库 Releases,3rd party 和 Central。也就是说我们在 pom.xml 引用这个仓库组,
其包含的仓库也被引用。
图 3
1.2.3.2 常规操作
1. 修改 admin 用户密码 点击左侧菜单栏的 Security——>Users,可看到系统默认的用户。点击 set pwd,
就可进行新密码的设置,如下图 4 所示。(需要注意:在发布构件一般需要帐号和
密码)
图 4 2. 新增用户
点击上方的 add 按钮,在弹出的界面中,设置必填项:角色,状态为激活。如下图
5 所示。
图 5
1.3 配置本地项目引用并使用私服
1.3.1 自动发布构件到 Nexus 仓库
1. 在工程的 pom.xml 中添加:distributionManagement 发布仓库(distributionManagement):负责管理构件的发布包和其他编译生成的支
撑文件,那么我们自主开发的 jar 需要上传到 Nexus 的时候需要在 pom 中增加
distributionManagement 节点进行自动打包上传。 配置上传的仓库有两个:snapshot 快照仓库和 release 发布仓库。snapshot 快照仓库用于保存开发过程中的不稳定版本,release 正式仓库则是用来保存稳定的发行版本。那么我们在项目中定义一个组件/模块为快照版本,只需要在 pom 文件中在该模块的版本号后加上-SNAPSHOT 即可(注意:这里必须是大写),在开发阶段,我们一般都是设置为快照版本。 maven2 会根据模块的版本号(pom 文件中的
version)中是否带有-SNAPSHOT 来判断是快照版本还是正式版本。如果是快照版本,那么在 mvn deploy 时会自动发布到快照版本库中。关键配置代码如下:
<repository>
<id>releases</id><!--ID 需要与你的 release 仓库的 Repository ID 一致-->
<url>http://192.168.74.163:8081/nexus/content/repositories/releases</url>
</repository>
<snapshotRepository>
<id>snapshots</id><!-- ID 需要与你的 snapshots 仓库的 Repository ID 一致-->
<url>http://192.168.74.163:8081/nexus/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
2. 修改本地 maven 的 settings.xml 文件,配置用户名/密码,关键配置代码如下:
<servers> <server> <id>releases</id> <username>admin</username> <password>admin123</password> </server> <server> <id>snapshots</id> <username>admin</username> <password>admin123</password> </server> |
</servers>
当然若你要上传构件到其他仓库,可依照如下代码进行配置:
<server>
<id>thirdparty</id>
<username>admin</username>
<password>admin123</password>
</server>
<server>
<id>central</id>
<username>admin</username>
<password>admin123</password>
</server>
3. 在 idea 中,工程所在目录下执行 mvn 命令(mvn:deploy) 将最终版本的包拷贝到远程的 Repository,使得其他的开发者或者工程项目可以共享。所部署的包就自动上传到了Nexus指定的仓库里。比如:上传jar包到snapshots 仓库。mvn:deploy 在整合或者发布环境下执行:
mvn deploy:deploy-file -DgroupId=cn.itrip -DartifactId=itrip-beans -Dversion=1.0-SNAPSHOT -Dpackaging=jar
-Dfile=D:\ideaworkspace\itripbackend\itripbeans\target\itrip-beans-1.0-SNAPSHOT.jar
-Durl=http://192.168.74.163:8081/nexus/content/repositories/snapshots/ -DrepositoryId=snapshots
➢ DgroupId 和 DartifactId 构成了该 jar 包在 pom.xml 的坐标,项目就是依靠
这两个属性定位。
➢ Dfile 表示需要上传的 jar 包的绝对路径。
➢ Durl 私服上仓库的位置,打开 nexus——>repositories 菜单,可以看到该路径。
➢ DrepositoryId 服务器的表示 id,在 Nexus 的 configuration 可以看到。
➢ Dversion 表示版本信息 上传成功后,在 Nexus 界面点击 snapshots 仓库可以看到这个包。还有一种上传构件的方式是手动上传,即通过 Nexus 的界面操作,较为简单,在此不再赘述。
1.3.2 配置 Maven 从 Nexus 下载构件
1. 首先配置 Maven 镜像 配置镜像目的就是让 Maven 只使用私服,修改 Maven 的 setting.xml 文件,具体配置如下。
<mirror> <id>nexus</id> <mirrorOf>*</mirrorOf> <name>local nexus repository</name> <url>http://192.168.74.163:8081/nexus/content/groups/public/</url> </mirror> |
在 pom 文件不做任何配置的情况下,默认是使用 id 为 central 的 Maven 中央库进行配置的。那么以上配置只取代了 pom 中的下载仓库,覆盖了 maven 默认的配置。 mirrorOf 配置为*,表示这个镜像配置适用于所有的仓库,是所有仓库的一个镜像, maven 无论要去那个仓库下载构件都会跳转到镜像 URL(此时配置的是 nexus 的 group 类型的仓库地址,该组仓库包含了其他几个类型的仓库)去下载,不会到中央资源库下载。当然 mirrorOf 也可以配置一个或多个仓库,多个仓库配置值要与对应的仓库 id 一致,以逗号分隔。
2. 修改项目的 pom 文件,设置下载仓库(repostories)
<repositories>
<repository>
<id>public</id>
<name>Team Maven Repository</name>
<url>http://192.168.74.163:8081/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled><!—是否支持更新—>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
注:上述配置只对当前项目有效,若需让本机所有 Maven 项目均使用该 Mavne 私
服,应该在 setting.xml 中进行配置。
3. 通过在settings.xml中配置profile元素,可以让本机所有的Maven项目都使用Maven 私服。
<profiles>
<profile>
<id>public</id>
<repositories>
<repository>
<id>public</id>
<name>Nexus</name>
<url>http://192.168.74.163:8081/nexus/content/groups/public/</url>
<release><enabled>true</enabled></release>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
</profile>
<profiles>
<activeProfiles><!--activeProfiles 用来激活-->
<activeProfile>public</activeProfile>
</activeProfiles>
Mvn package(打包)
Mvn deploy(发布)