关于java:基于JenkinsMavenGiteaNexus从0到1搭建CICD环境

0次阅读

共计 9453 个字符,预计需要花费 24 分钟才能阅读完成。

在传统的单体软件架构中,软件开发、测试、运维都是以单个过程为单位。

当拆分成微服务之后,单个利用能够被拆分成多个微服务,比方用户零碎,能够拆分成根本信息管理、积分治理、订单治理、用户信息管理、合同治理等多个微服务模块。

这个时候对每个模块别离打包、公布运行、开发、测试、运维的,对于测试、运维的工作量会极大减少。

在这个过程中,如果不足自动化测试、自动化集成 / 部署、主动运维等能力,带来的影响是

  1. 软件交付周期减少
  2. 多环境部署的状况下,各个环境差别带来的问题。
  3. 人工运维容易给环境带来一些不可重现的影响,而且一旦产生运维谬误又比拟难立即复原,造成故障解决工夫较长。并且对于运维人员的能力要求较高

所有的这些问题,会导致软件交付工夫变长、危险减少、以及运维成本增加等问题。因而,咱们须要一套自动化部署体系,来构建一个 CICD 的模型。

一般 Jar 包的运行形式

  1. 应用maven package
  2. nohup java -jar ${APP_NAME} > goods-service.log 2>&1 &
  • nohup 用处:不挂断地运行命令
  • & 用处,在后盾运行
  • 2>&1: 在 bash 中:

    • 0 代表 STDIN_FILENO 规范输出(个别是键盘),
    • 1 代表 STDOUT_FILENO 规范输入(个别是显示屏,精确的说是用户终端控制台),
    • 2 三代表 STDERR_FILENO (规范谬误(出错信息输入)。

    2>&1 就是用来将规范谬误 2 重定向到规范输入 1 中的。此处 1 后面的 & 就是为了让 bash 将 1 解释成规范输入而不是文件 1。至于最初一个 &,则是让 bash 在后盾执行。

  • > 间接把内容生成到指定文件

搭建 Nexus 私服环境

Nexus 是一个弱小的 Maven 仓库管理器,它极大地简化了本地外部仓库的保护和内部仓库的拜访。Nexus 是一套“开箱即用”的零碎不须要数据库,它应用文件系统加 Lucene 来组织数据。

Maven 私服环境须要用sonatype nexus,上面咱们从装置和配置进行详细分析

部署服务器:192.168.8.138

下载和装置

  1. 拜访:https://sonatype-download.global.ssl.fastly.net/repository/downloads-prod-group/3/nexus-3.37.0-01-unix.tar.gz地址,下载 Sonatype Nexus。
  2. 解压缩到 /data/program 目录下
[root@localhost program]# tar -zxvf nexus-3.37.0-01-unix.tar.gz 
  1. 进入到 ${NEXUS_HOME}\bin 目录,执行上面命令启动 Nexus
./nexus start 

装置 Maven

  1. 下载 Maven: https://dlcdn.apache.org/maven/maven-3/3.8.4/binaries/apache-maven-3.8.4-bin.tar.gz
  2. 配置 Maven 和 JDK 环境变量。
export JAVA_HOME=/data/program/jdk1.8.0_241
export MAVEN_HOME=/data/program/apache-maven-3.8.4
export PATH=$JAVA_HOME/bin:$MAVEN_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
  1. 进入到 ${NEXUS_HOME}\bin 目录,执行上面命令启动 Nexus

    用./nexus start 启动,后盾启动,启动胜利后能够拜访

    用./nexus run 启动,前台启动,显示日志,启动后能够拜访

./nexus start 

启动时,会有如下提醒,这个是倡议咱们应用非 root 账户来拜访。

WARNING: ************************************************************
WARNING: Detected execution as "root" user.  This is NOT recommended!
WARNING: ************************************************************
  1. 拜访:http://localhost:8081拜访 Nexus 仓库

如果想配置 nexus 的利用在本地启动的 JVM 参数,能够在 nexus.vmoptions

如果想扭转 nexus 的 端口号,能够在 nexus-default.properties

登录控制台

  1. 默认登录的帐号是 admin,明码在会提醒你在:/data/program/sonatype-work/nexus3/admin.password 文件中。

  1. 内容如下,间接复制该内容登录即可。
090849ac-cea7-4353-b2c8-59b2bceadb50

Nexus 控制台阐明

进入 Nexus 控制台的 Browse 菜单,能够看到四种仓库类型:

1)maven-central:maven 地方库,默认从 https://repo1.maven.org/maven2/ 拉取 jar

2)maven-releases:私库发行版 jar

3)maven-snapshots:私库快照(调试版本)jar

4)maven-public:仓库分组,把下面三个仓库组合在一起对外提供服务,在本地 maven 根底配置 settings.xml 中应用。

Nexus 默认的仓库类型有以下四种:(下面的名字能够轻易取,要害是它对应的是什么仓库类型)

1)group(仓库组类型):又叫组仓库,用于不便开发人员本人设定的仓库;

2)hosted(宿主类型):外部我的项目的公布仓库(外部开发人员,公布下来寄存的仓库);

3)proxy(代理类型):从近程地方仓库中寻找数据的仓库(能够点击对应的仓库的 Configuration 页签下 Remote Storage Location 属性的值即被代理的近程仓库的门路);

4)virtual(虚构类型):虚构仓库(这个根本用不到,重点关注下面三个仓库的应用);

Nuget 是用于微软.NET 开发平台的软件包管理器,和 Maven 相似。

目录阐明

nexus-3.34.0-01 目录

  1. bin 蕴含 nexus 的启动脚本和相干配置
  2. etc jetty、karaf 等配置文件
  3. jre jre 环境
  4. lib java 架包库
  5. public 对于 nexus 利用在本地跑起来所须要的资源
  6. system 利用所有的插件和组件
  7. LICENSE.txt 和 NOTICE.txt 版权申明和法律细则

sonatype-work\nexus3 目录

  1. blobs/ 创立 blob 的默认门路,当然也能够从新指定
  2. cache/ 以后缓存的 karaf 包的信息
  3. db/ OrientDB 数据库的数据,用于存储 nexus 的元数据的数据库
  4. elasticsearch/ 以后配置的 Elasticsearch 状态
  5. etc/ 大略是运行时配置状态和对于资源库的自定义的相干的货色
  6. health-check/ 看目录,健康检查的相干报告的存储目录吧
  7. keystores/ 主动生成的对于资源库的 ID 主键
  8. log/ 运行实例生成的日志文件,也有日志文件的压缩包,貌似是每天都会生成日志文件,你能够定期删除老的日志文件
  9. tmp/ 用于存储临时文件的目录

Nexus 设置成零碎服务

依照以下步骤执行

  1. 批改 ${NEXUS_HOME}\bin\nexus 这个脚本,减少上面的配置
INSTALL4J_JAVA_HOME_OVERRIDE=/data/program/jdk1.8.0_241
  1. 设置软链接
[root@localhost bin]# ln -s /data/program/nexus-3.37.0-01/bin/nexus /etc/init.d/nexus
  1. 通过 chkconfig 形式配置零碎服务
cd /etc/init.d
sudo chkconfig --add nexus #增加 nexus 服务
sudo chkconfig --levels 345 nexus on #设置开启自启动
  1. 启动和进行服务

    sudo service nexus start #开启服务
    service nexus status #查看服务状态

搭建 Gitea 环境

参考文档:https://docs.gitea.io/zh-cn/i…

  1. 装置 git 环境: yum -y install git
  2. 通过上面的命令下载 linux 中的安装包到 /data/program/gitea 目录下。
wget -O gitea https://dl.gitea.io/gitea/1.15.7/gitea-1.15.7-linux-amd64
  1. 执行 chmod +x gitea 命令,授予执行权限
  2. 执行上面这个命令运行 gitea
./gitea web

装置成零碎服务(重要)

  1. 创立 Git 用户
sudo useradd \
   --system \
   --shell /bin/bash \
   --comment 'Git Version Control' \
   --create-home \
   --home /home/git \
   git
  1. 下载二进制文件
wget -O gitea https://dl.gitea.io/gitea/1.15.7/gitea-1.15.7-linux-amd64
  1. 依据 gitea 官网举荐,依照以下形式配置 gitea 的装置目录

    • 把下载的文件挪动到 /usr/local/bin 目录

      sudo mv /data/program/gitea /usr/local/bin
    • 使二进制文件可执行:

      chmod +x /usr/local/bin/gitea
    • 依照一下命令创立必要目录并设置权限

      sudo mkdir -p /var/lib/gitea/{custom,data,indexers,public,log}
      sudo mkdir -p /var/lib/gitea/{custom,data,indexers,public,log}
      sudo chown git: /var/lib/gitea/{data,indexers,custom,public,log}
      sudo chmod 750 /var/lib/gitea/{data,indexers,log}
      sudo mkdir /etc/gitea
      sudo chown root:git /etc/gitea
      sudo chmod 770 /etc/gitea
    • 依据 Gitea 官网提供的 Systemd Unit 文件,配置零碎服务。

      sudo wget https://raw.githubusercontent.com/go-gitea/gitea/master/contrib/systemd/gitea.service -P /etc/systemd/system/

      留神,gitea.service,不能通过 wget 下载,须要去 github 上复制

    • 实现上述过程后,通过上面命令开启主动启动

      systemctl enable gitea
      systemctl start gitea
  2. 装置启动实现后,拜访:http://192.168.8.136:3000,配置数据库相干属性即可。

搭建 Jenkins 环境

Jenkins 是一个用 JAVA 编写的开源的继续集成工具,运行在 servlet 容器中,反对软件配置管理 (SCM) 工具,能够执行基于 APACHE ANT 和 APACHE MAVEN 的我的项目,以及任意 Shell 脚本和 Windows 批处理命令

Jenkins 提供了主动构建和部署的性能,具体装置形式如下:

wget -O /etc/yum.repos.d/jenkins.repo \
    https://pkg.jenkins.io/redhat-stable/jenkins.repo
rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
yum upgrade
yum install epel-release java-11-openjdk-devel
yum install jenkins
systemctl daemon-reload

通过上面的命令启动或进行 jenkins

systemctl start jenkins
systemctl stop jenkins

拜访:http://192.168.8.136:8080 拜访 jenkins

依照控制台提醒的步骤一步步执行即可。

留神:Jenkins 装置默认采纳 JENKINS 用户,所以如果是应用 root 权限,则须要批改帐号

[root@localhost bin]# vim /etc/sysconfig/jenkins

JENKINS_USER="root"

我的项目革新

我的项目配置本地的私服

  1. 批改 setting.xml 文件,减少 mirror 配置

    <mirrors>
        <mirror>
            <id>nexus</id>
            <mirrorOf>maven-public</mirrorOf>
            <url>http://192.168.8.136:8081/repository/maven-public/</url>
        </mirror>
    </mirrors>

    mirror 相当于一个拦截器,它会拦挡 maven 对 remote repository 的相干申请,走该镜像进行 jar 包的获取。

  1. 在我的项目中减少如下配置,也就是指定 snapshots 和 releases 不同发行版本 jar 包的公布仓库

    <distributionManagement>
        <snapshotRepository>
            <id>snapshots</id>
            <name>Nexus Snapshot Repository</name>
            <url>http://192.168.8.136:8081/repository/maven-snapshots/</url>
        </snapshotRepository>
        <repository>
            <id>releases</id>
            <name>Nexus Release Repository</name>
            <url>http://192.168.8.136:8081/repository/huhy-nexus/</url>
        </repository>
    </distributionManagement>

批改公布服务器的 settings.xml 文件

批改公布服务器的 settings.xml 文件的目标,是因为 Jenkins 服务器在进行继续集成时,须要通过 maven 实现依赖 jar 包的下载,而这个下载须要从咱们本地的私服中获取。

<mirrors>
    <mirror>
        <id>nexus</id>
        <mirrorOf>maven-public</mirrorOf>
        <url>http://192.168.8.136:8081/repository/maven-public/</url>
    </mirror>
</mirrors>
<profiles>
     <profile>
      <id>nexusRep</id>
      <repositories>
        <repository>
          <id>nexus</id>
          <url>http://192.168.8.136:8181/repository/maven-public/</url>
          <layout>default</layout>
          <releases>
              <enabled>true</enabled>
              <updatePolicy>always</updatePolicy>
          </releases>
        </repository>
      </repositories>
      <pluginRepositories>  
        <pluginRepository>  
          <!-- 插件地址 --> 
            <id>nexus</id>  
            <url>http://192.168.8.136:8181/repository/maven-public/</url>  
            <snapshots>     
              <enabled>true</enabled>    
            </snapshots>    
            <releases>      
                <enabled>true</enabled>    
            </releases> 
        </pluginRepository>
       </pluginRepositories>
    </profile>
  </profiles>

  <activeProfiles>
    <activeProfile>nexusRep</activeProfile>
  </activeProfiles>

配置主动集成与公布

配置 Jenkins 的环境变量

进入到如下页面,红色标注的配置。

配置 Maven 的环境,指定公布服务器上安装的 Maven 目录。

装置 Jenkins 插件

  • Gitea,集成 Gitea,装置好之后,在 Jenkins 全局配置中,增加 Gitea Server 信息。

  • Git Parameter , 配置 Git 公布属性
  • Publish Over SSH , 在近程机器上执行脚本,这一步须要先配置能 ssh 近程机器
  • Maven Integration,反对 Maven 我的项目的集成

配置公布指标服务器信息

咱们把上面两台服务器当成是 web 节点

  1. 192.168.8.134
  2. 192.168.8.135

在 Jenkins 全局配置中,配置这两台服务器的信息,用来后续实现 jar 包近程传输。其中 Remote Directory 指标服务器的工作目录,jar 包会被近程传输到该目录下

增加我的项目公布机制

创立一个 Maven 我的项目的工作。

配置源码起源,这里应用 Gitea 中我的项目的源码地址,并配置登录帐号密码信息。

配置 Maven 的执行命令,其中root POM,如果是在多模块我的项目中,须要指定以后要构建的模块的 pom.xml。

减少构建胜利之后的执行逻辑,就是把 jar 包公布到远程目标服务器,而后执行相干 shell 脚本启动服务

编写公布脚本

编写 shell 脚本,当 jar 包发送到指标服务器之后,执行上面脚本。

  1. 做历史 jar 备份和清理
  2. 执行 shell 脚本启动服务
#! bin/sh -e
export JAVA_HOME=/data/program/jdk1.8.0_241
export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=${PATH}:$JAVA_HOME/bin
source /etc/profile 

# define property
JAR_PATH='/app/service/goods-service'
TEMP_PATH='/app/service/temp'
BACKUP_PATH='/app/service/backup'
JAR_NAME=goods-service.jar
FILE_NAME=goods-service

# stop target service
cd ${JAR_PATH}
sh run-goods-service.sh stop
sleep 2
rm -rf $FILE_NAME.log

# backup old jar
BACKUP_DATE=$(date +%Y%m%d_%H%M)

if [! -d $JAR_PATH/backup/$FILE_NAME];then
    mkdir -p $JAR_PATH/backup/$FILE_NAME
fi

cd ${JAR_PATH}
pwd
if [-f $JAR_NAME];then
   mv -f ./$JAR_NAME ./backup/$FILE_NAME/$JAR_NAME$BACKUP_DATE
   sleep 1
fi

# start jar
BUILD_ID=dontKillMe
cd ${TEMP_PATH}
mv -f $JAR_NAME  $JAR_PATH
cd ${JAR_PATH}
sh run-goods-service.sh restart

# clear old backup
cd ${JAR_PATH}/backup/$FILE_NAME
ls -lt|awk 'NR>5{print $NF}' |xargs rm -rf

ps -ef|grep java
echo "=============deploy success========"

编写运行脚本 run-goods-service.sh

# 示意以后脚本采纳 /bin 门路的 bash 程序来解释执行
#!/bin/bash

# 执行的 jar 包
APP_NAME=goods-service.jar

usage() {echo "执行操作命令 [start|stop|restart|status]"
  exit 1
}

if_exist() {pid=`ps -ef|grep $APP_NAME|grep -v grep|awk '{print $2}'`
  if [-z "${pid}" ]; then
    return 1
  else
    return 0
  fi
}

start() {
  if_exist
  if [$? -eq 0]; then
    echo "${APP_NAME} already running . pid=${pid}"
  else
    nohup java -jar ${APP_NAME} > goods-service.log 2>&1 &
    npid=`ps -ef|grep $APP_NAME|grep -v grep|awk '{print $2}'`
    echo "start ${APP_NAME} success, pid=${npid}"
  fi
}

stop() {
  if_exist
  if [$? -eq 0]; then
    kill -9 $pid
    echo "stop $pid success".
  else
    echo "${APP_NAME} is not running"
  fi
}

status() {
  if_exist
  if [$? -eq 0]; then
    echo "${APP_NAME} is running. pid is ${pid}"
  else
    echo "${APP_NAME} is not running"
  fi
}

restart() {
  stop
  sleep 5
  start
}

case "$1" in
   "start")
      start
       ;;
    "stop")
      stop
       ;;
    "status")
      status
       ;;
    "restart")
      restart
       ;;
    *)
    usage
     ;;
esac

配置代码提交后动静构建

如果咱们心愿代码提交合并到某个分支后,主动构建进行公布,怎么实现呢?

装置 Webhook 插件

  1. 在 Jenkins 中装置Generic Webhook Trigger 插件,装置胜利后,会在构建的配置页面多了上面所示的一个选项。

  2. 配置Generiac Webhook Trigger,减少一个 token 作为验证。

    留神这个地址:http://JENKINS_URL/generic-we…,在 webhook 中须要配置这个作为触发调用。

gitea 增加 webhook 钩子

  1. 在 gitea 的我的项目中,找到Web 钩子,增加Web 钩子. 抉择gitea

  2. 增加 webhook

验证主动触发的行为

  1. 批改 gpmall-pc 这个我的项目的任何一个代码,而后提交到 gitea 上。
  2. 察看 Jenkin 的我的项目构建目录,会减少一个主动构建的工作,如下图所示。

  3. 并且在 gitea 的 webhook 中,能够看到最近的推送记录

源码地址

文章演示应用的源码:https://github.com/2227324689…

版权申明:本博客所有文章除特地申明外,均采纳 CC BY-NC-SA 4.0 许可协定。转载请注明来自 Mic 带你学架构
如果本篇文章对您有帮忙,还请帮忙点个关注和赞,您的保持是我一直创作的能源。欢送关注同名微信公众号获取更多技术干货!

正文完
 0