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

当拆分成微服务之后,单个应用可以被拆分成多个微服务,比如用户系统,可以拆分成基本信息管理、积分管理、订单管理、用户信息管理、合同管理等多个微服务模块。

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

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

  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/install-from-binary/

  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包的获取。

  2. 在项目中增加如下配置,也就是指定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-webhook-trigger/invoke , 在webhook中需要配置这个作为触发调用。

gitea添加webhook钩子

  1. 在gitea的项目中,找到Web钩子,添加Web钩子. 选择gitea

  2. 添加webhook

验证自动触发的行为

  1. 修改gpmall-pc这个项目的任何一个代码,然后提交到gitea上。

  2. 观察Jenkin的项目构建目录,会增加一个自动构建的任务,如下图所示。

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

源码地址

文章演示使用的源码: https://github.com/2227324689/spring-cloud-netflix-example.git

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Mic带你学架构

如果本篇文章对您有帮助,还请帮忙点个关注和赞,您的坚持是我不断创作的动力。欢迎关注「跟着Mic学架构」公众号公众号获取更多技术干货!

基于Jenkins+Maven+Gitea+Nexus从0到1搭建CICD环境的更多相关文章

  1. dokcer自动化构建部署java web 基于jenkins+maven+nuxus容器

    # dokcer自动化构建部署java web 基于jenkins+maven+nuxus容器 #环境centos 7.4 docker 18.03.0-ce # nuxus,创建maven本地源(可 ...

  2. vue.js2.0实战(1):搭建开发环境及构建项目

    Vue.js学习系列: vue.js2.0实战(1):搭建开发环境及构建项目 https://my.oschina.net/brillantzhao/blog/1541638 vue.js2.0实战( ...

  3. Jenkins+Maven+Gitlab+Nexus持续集成环境搭建

      1.软件及服务介绍 Jenkins:jenkins是实现代码自动化流程上线的工具,Jenkins是一个独立的开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个 ...

  4. Jenkins+Maven+SVN+Nexus自动化部署代码实例

    本文接着上篇安装jenkins,安装相关插件,使用我们公司持续集成的测试环境实例进行演示 ========= 完美的分割线 ========== 1.安装jenkins的maven插件 如果要使用je ...

  5. 基于 Jenkins + Kubernetes + Argo CD 的完整 DevOps 流程记录(1) - 环境部署

    一.环境准备 1.1 镜像仓库 整套 DevOps 流程使用 Harbor 作为内部镜像仓库,所有构建产物(镜像)都会推送到 Harbor,以备后续进行项目部署.Harbor 从 2.x 版本开始支持 ...

  6. 基于HTML5的SLG游戏开发(一):搭建开发环境(1)

    开发环境: 1.操作系统:MacOS 10.8.5 2.本地web服务器:Apache 2.2.24 (Window环境推荐使用WampServer) 3.编码工具:WebStrom 7.0 4.调试 ...

  7. 基于HTML5的SLG游戏开发(一):搭建开发环境(2)

          游戏开发过程中经常需要处理各种事件,而HTML5游戏开发中,所有的场景和UI面板都是绘制在Canvas上面,假设需要对某一UI面板上的关闭按钮添加事件监听,采取的方法是对关闭按钮图片资源进 ...

  8. jenkins + maven + nexus + [ svn 或 GitLab 或 GitHub ]

    目录 介绍 DevOps平台四大模块 针对DevOps开源项目 Jenkins 介绍 Maven 介绍 maven的核心概念介绍 SVN介绍 Nexus介绍 Maven私服的 个特性: 流程图 环境搭 ...

  9. 基于Jmeter+maven+Jenkins构建性能自动化测试平台

      一.目的: 为能够将相关系统性能测试做为常规化测试任务执行,且可自动无人值守定时执行并输出性能测试结果报告及统计数据,因此基于Jmeter+maven+Jenkins构建了一套性能自动化测试平台 ...

随机推荐

  1. Xpath 使用技巧

    使用xpath 简介 常见语法 选取节点 谓语 通配符 选取多个路径 运算符 其他用法 使用contains选取包含属性 使用tostring()将对象转换为字符串 使用starts-with 使用n ...

  2. Table.RenameColumns重命名…Rename…(Power Query 之 M 语言)

    数据源: "姓名""基数"等列 目标: 修改"姓名"列标题为"员工姓名" 操作过程: [转换]>[重命名]> ...

  3. Arcpy按属性(字段值)不同将shp分割为多个独立shp_适用点线面矢量

    利用代码可以进行批量处理,安装有10.5及以上版本ArcGIS可以使用工具Split by attributes完成上述任务 # -*- coding: utf-8 -*- # Import syst ...

  4. 系统分析师教程(张友生)高清pdf下载

    最近准备考系统分析师,故找了一本张又生编著的<系统分析师教程>的电子书,本来想买本书,可惜有点小贵,舍不得,故寻找电子版下载,花了不少时间才找到,现在分享给大家. http://item. ...

  5. CountDownLatch源码阅读

    简介 CountDownLatch是JUC提供的一个线程同步工具,主要功能就是协调多个线程之间的同步,或者说实现线程之间的通信 CountDown,数数字,只能往下数.Latch,门闩.光看名字就能明 ...

  6. 1336 - Sigma Function

    1336 - Sigma Function   PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB S ...

  7. Pikachu漏洞练习-SQL-inject(二)

     

  8. 「算法笔记」BSGS 与 exBSGS

    一.离散对数 给定 \(a,b,m\),存在一个 \(x\),使得 \(\displaystyle a^x\equiv b\pmod m\) 则称 \(x\) 为 \(b\) 在模 \(m\) 意义下 ...

  9. [炼丹术]UNet图像分割模型相关总结

    UNet图像分割模型相关总结 1.制作图像分割数据集 1.1使用labelme进行标注 (注:labelme与labelImg类似,都属于对图像数据集进行标注的软件.但不同的是,labelme更关心对 ...

  10. Java初学者作业——使用eclipse简单的输出(打印)游戏菜单

    返回本章节 返回作业目录 需求说明: 使用eclipse创建Java项目,在Java程序中输出游戏菜单. 为 Java 程序添加单行和多行注释. 实现思路: 在 eclipse 中创建项目及Java类 ...