聚沙成塔:巧用 Nexus 搭建 Maven 私服

前言

  在互联网行业中,成熟的公司都会有专门的技术团队开发出各式各样的产品供用户使用。对于公司内部的不同产品而言,并不是每一个产品都需要重零构建,大多数情况下都是在旧产品基础上组合拼凑,衍生出新产品。
  如果说 B、C 产品都是在 A 产品基础上开发的新产品,那么意味着什么呢?
  对程序员而言,这代表着继承,也可以说是代码复用。
  那么,就有个问题了,如何去让 B、C 产品的代码继承 A 产品代码呢?
  A 产品代码打个包嘛,每个 Java 程序员都会使用 Maven,引入下不就好了?
  话是这么说,但是有个问题,A 产品的包放在哪里?不可能放中央仓库吧?这可是公司内部的产品呀!
  嘿嘿,这个时候,就需要专门搭建一个存放公司产品包的仓库,去管理这些内部产品包了。(这种内部产品包被称为二方包,公司搭建的仓库被成为二方库)。

  一般而言,公司内部的二方库早就有开发搭建好了,用不着新人动手,但由于罗马并不是一天就能建成的,有的公司技术部门可能刚刚创立,会存在没搭建过私服的情况,这个时候就需要我们手动动手了。

  那么,下面跟随本文来搭建一个 Maven 私服吧!

Nexus 简介

  Nexus 是 Sonatype 公司发布的一款仓库(Repository)管理软件,常用来搭建 Maven 私服,当然其不仅仅可以用来搭建 Maven 私服哦~

Nexus 部署

前提

  系统必须已安装 JDK8,若没有安装也可执行以下命令自动安装:

1
yum install -y java-1.8.0-openjdk-devel.x86_64

下载

  点击下载地址选择不同操作系统的 Nexus 包进行下载。
  由于一般使用 Linux 系统,所以我们这里下载 unix 系统的nexus-3.38.0-01-unix.tar.gz

解压

1
tar xvzf nexus-3.38.0-01-unix.tar.gz -C /data/nexus

  解压后我们将得到以下两个目录:

1
2
├── nexus-3.38.0-01  # nexus 服务
└── sonatype-work # 私有库目录

文件配置

端口号

  Nexus 默认使用8081端口,若想修改可以在配置文件中修改:

1
vim nexus-3.38.0-01/etc/nexus-default.properties

JVM

1
2
3
4
vim /data/nexus/nexus-3.38.0-01/bin/nexus.vmoptions
# 内存占用可以改小点
-Xms1824m
-Xmx1824m

用户权限

1
2
3
4
5
6
7
8
9
# 新增 nexus 用户并设置密码
sudo adduser nexus
sudo passwd nexus
# 授予目录权限
sudo chown -R nexus:nexus /data/nexus
# 调整文件描述符打开数量;
sudo vim /etc/security/limits.conf
### 增加以下配置
nexus - nofile 65536
1
2
3
vim /data/nexus/nexus-3.38.0-01/bin/nexus.rc
# 修改如下
run_as_user="nexus"

启动

  进入nexus-3.38.0-01/bin目录, 运行./nexus start脚本即可启动服务

可能遇到的问题

  第一次启动未完成时终止会导致数据异常,这些数据都存放在sonatype-work文件中,因此可以考虑删除此文件重新解压个新的,之后重新启动即可。

测试

  访问http://192.168.3.102:8081进入 UI 界面,点击右上角Sign in登陆,第一次登陆会告知密码文件的路径。

异常情况处理

  查看 Nexus 日志,发现总是爆以下错误:

1
2
3
4
5
6
7
8
9
*UNKNOWN com.sonatype.nexus.plugins.outreach.internal.outreach.SonatypeOutreach - Could not download page bundle
org.apache.http.conn.HttpHostConnectException: Connect to sonatype-download.global.ssl.fastly.net:443 [sonatype-download.global.ssl.fastly.net/69.171.245.49] failed: 连接超时
at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:151) [httpcore:0.0.0]
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353) [httpcore:0.0.0]
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380) [httpcore:0.0.0]
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236) [httpcore:0.0.0]
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184) [httpcore:0.0.0]
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88) [httpcore:0.0.0]
`

  报此错误的原因是 Nexus 的欢迎页面会从 Sonatype 重定向一些信息进行展示,此功能叫做 Outreach,由于其地址是国外的导致无法访问,因此你会发现你的欢迎页面是空荡荡的,什么都没有。
  既然用不到这个功能,也为了避免周期性的报错,可以把 Outreach 禁用。
  如何禁用呢?
  处理方法:

  • 以管理员身份登录
  • 依次选择Administration -> System -> Capabilities,选择Outreach Management功能
  • 点击 Disable 按钮即可,修改会立马生效

扩展—— Nginx 反向代理 Nexus

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
server {
listen 443 ssl;
server_name nexus.lee.com;
# 上传文件限制 200M
client_max_body_size 200M;

# 证书文件名称
ssl_certificate /etc/nginx/certificate/nexus/nexus.lee.com_bundle.crt;
# 私钥文件名称
ssl_certificate_key /etc/nginx/certificate/nexus/nexus.lee.com.key;
ssl_session_timeout 5m;
# 请按照以下协议配置
ssl_protocols TLSv1.2 TLSv1.3;
# 请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
# 代理设置
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 "https";

location / {
proxy_pass http://127.0.0.1:8081;
}

}

Nexus 管理依赖包

  既然前面我们使用 Nexus 搭建好了私服,那么现在,如何通过它去管理依赖包呢?
  如何管理依赖包?前提是要知道我们有什么类型的包要管理,我们有什么包要管理?不是就二方包嘛?
  哈哈,你想的不全对,其实,私服可以管理三种类型的包:

  • 二方包:前面说过的公司内部产品的包,若新产品需要,则需要上传到私服中
  • 三方包(开源):如 Apache、Google 等开源的包,中央仓库可以找到,但去中央仓库下载比较花时间,可以缓存到私服中内网直接快速下载
  • 三方包(非开源):如与公司合作的第三方公司开发的包,一般提供在接口文档中,中央仓库不一定找到,也可以上传到私服,不然由于坐标问题不好解决打包问题

  这些不同类型的包存放到私服的作用不同:

  • 二方包是因为其他项目需要使用
  • 三方包(开源)是为了缓存,提升项目构建速度
  • 三方包(非开源)是为了解决坐标问题,对接第三方产品需要打包

仓库配置

新增仓库

  默认情况下,中央仓库服务器在国外,为了提高速度,我们使用阿里云的镜像仓库,我们点击Create repository新增代理仓库,添加以下地址:

1
https://maven.aliyun.com/nexus/content/repositories/central/

  勾选地址输入框下面的单选框,选择证书并添加,最后保存即可添加此代理仓库。

  添加完成后在仓库组选中此代理仓库,并将使用优先级设置在中央仓库之前。

部署发布角色用户

  Nexus 存在不同权限的用户,admin 用户具有所有权限,若仅仅是想从 Nexus 仓库中下载依赖包或者部署包到 Nexus 仓库中,可以专门创建一个仅有这些权限的一个用户来处理此工作。
  创建此用户步骤如下:

  • ① 新建一个专门用于部署的角色nx-deploy,选择以下权限并继承nx-anonymous角色

    1
    2
    nx-repository-view-*-*-edit
    nx-repository-view-*-*-read
  • ② 新建一个专门用于部署的用户(如deployer),选择nx-deploy角色,配置密码即可

包部署

二方包部署

  在二方包部署前,我们需要对 Maven 的一些文件进行配置:

  • 修改setting.xml文件,配置私服的认证信息(使用前面的部署用户名及密码)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <!-- deploy 时需要配置服务器认证信息 -->
    <server>
    <id>nexus-releases</id>
    <username>deployer</username>
    <password>123456</password>
    </server>
    <server>
    <id>nexus-snapshots</id>
    <username>deployer</username>
    <password>123456</password>
    </server>
  • 修改项目根级pom.xml文件,指定发布到私服中的哪个仓库

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <!-- Deploy 注意事项:repository id 必须与 setting.xml 文件中的 server id 对应 -->
    <distributionManagement>
    <repository>
    <id>nexus-releases</id>
    <url>http://nexus.lee.com/repository/maven-releases/</url>
    </repository>
    <snapshotRepository>
    <id>nexus-snapshots</id>
    <url>http://nexus.lee.com/repository/maven-snapshots/</url>
    </snapshotRepository>
    </distributionManagement>

  配置完以上参数后,可以直接通过 IDEA 的 Maven 插件中的 deploy 进行二方包的部署。

注意

  如果 Nexus 配置了 HTTPS,上面配置的<url>中也需要使用https,否则deploy时可能由于检查文件校验和导致上传速度非常非常慢。

三方包(非开源)部署

   三方包(非开源)无法直接通过 Maven 插件进行部署,我们需要使用以下命令完成部署工作:

1
mvn deploy:deploy-file -DgroupId=cn.lee -DartifactId=watermark -Dversion=1.0 -Dpackaging=jar -Dfile=/Users/wk/Downloads/fdd.jar -Durl=http://nexus.lee.com/repository/maven-releases/ -DrepositoryId=nexus-releases

  参数说明:

  • DgroupId:等同于pom中的groupId,建议设置为公司域名反写
  • DartifactId:等同于pom中的artifactId,建议设置为包名
  • Dversion:等同于pom中的version,建议设置为 1.0
  • Dpackaging:等同于pom中的packaging,建议设置为 jar
  • Dfile:准备上传三方包的绝对路径
  • Durl:上传的仓库url,建议发布到 Releases 仓库
  • DrepositoryId: 必须与本地安装的Maven中的setting.xml文件中的serverid属性值保持一致

备用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
location ^~ /service/ {
proxy_pass http://localhost:8081/service/;
}

location ^~ /repository/ {
proxy_pass http://localhost:8081/repository/;
}

location ^~ /images {
proxy_pass http://localhost:8081/images;
}

location ^~ /static {
proxy_pass http://localhost:8081/static;
}

location ^~ /icons {
proxy_pass http://localhost:8081/icons;
}

快照版本发布配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<profiles>
<profile>
<id>nexus</id>
<repositories>
<repository>
<id>central</id>
<url>http://nexus.zksj.com.cn/repository/maven-public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>nexus</id>
<url>http://nexus.zksj.com.cn/repository/maven-public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>

<activeProfiles>
<activeProfile>nexus</activeProfile>
</activeProfiles>

小结

  通过本文,我们梳理学习了以下知识:

  • 私服的作用
  • Maven 私服的管理软件 Nexus
  • Nexus 的安装部署过程
  • Nexus 管理依赖包的流程

参考

  • 许晓斌. Maven 实战 [M]. 机械工业出版社,2010

文章信息

时间 说明
2022-03-19 初稿
2022-03-26 完稿
0%