栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【自动化运维】从0到1 CICD自动化部署落地分享

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【自动化运维】从0到1 CICD自动化部署落地分享

目录

一、CICD简介

二、CICD实践过程

三、含泪踩坑

四、历史文章指路

一、CICD简介

1、CICD定义

Continuous Integration (CI) 持续集成

Continuous Delivery (CD) 持续交付

Continuous Deployment (CD) 持续部署

2、DevOps定义

DevOps(Development和Operations的组合词)是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(QA)部门之间的沟通、协作与整合。

DevOps的基础核心是CICD。

CICD的基础核心是自动化。

二、CICD实践过程

1、起因

在我之前的团队,因为要切换全新业务线,需要为新业务搭建一套全新的环境,所有东西从0开始。

原先只是用于部署测试环境,后面决定一起部署生产环境,这个过程中我还造成了一个严重生产环境问题,好在当时的生产环境还未正式使用,未造成严重影响。

在当时挺害怕也挺有压力的,但是后面项目完整落地,平稳运行,我还是挺有成就感的,接下来我将整个项目过程完整的分享出来。

2、技术栈选型

首先进行技术栈选型,我们选择的是Jenkins,Jenkins当属业内持续集成老大哥,有着非常丰富的插件,也可以选择gitlab集成的CICD,因为我们还有其它的测试脚本需要集成,所以Jenkins对于我们来说是最优的选择;

Ansible是批量运维工具,通过编写yaml脚本,可以方便实现批量管理多台机器,并且Ansible是比较轻量级应用,很容易上手;

shell脚本可以用于执行一系列命令。

其它的就结合团队项目情况进行搭建。

Jenkins–持续集成

Ansible–下发文件

Shell–Linux脚本

Git–版本管理

GitLab–代码托管

Node.js–前端编译

Maven–后端编译

JDK–Java运行环境

Nginx–请求代理

Dubbo–RPC框架

Disconf–配置中心

Redis–缓存数据库(购买阿里云服务)

Zookeeper–中间件(购买阿里云服务)

RDS(MySQL)–数据库(购买阿里云服务)

3、Jenkins应用部署实现流程

首先来梳理下整个项目的实现流程,主要分为Jenkins主节点和应用服务器,是一对多的关系。

Jenkins主节点的主要负责项目部署前的工作,主要包含拉取代码,前端打包,后端打包,快照版检测,将压缩包和部署脚本发送到目标机器(即应用服务器),远程调用目标机器上的部署脚本进行代码替换。

应用服务器部署脚本执行过程有:解压压缩包,停止服务,覆盖代码,拉取disconf,应用目录分组赋权,重启服务,检查服务是否有进程,查看启动日志,删除/tmp目录下旧压缩包。

Jenkins应用部署流程图

4、任务计划

4.1、搭建环境

Jenkins

指路【Jenkins系列】如何搭建Jenkins环境。

Ansible

1、安装Ansible
yum install ansible -y

2、查看版本信息
ansible -version

Git

1、安装Git
yum install git -y

2、查看版本信息
git --version

GitLab

因为这个我没有实践成功的教程,所以在这里就不贴啦~

Node.js

1、解压node安装包,注:参数不用z
tar xvf node-v6.16.0-linux-x64.tar -C /data

2、安装cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org

3、在/usr/bin目录下设置软连接
ln -s  /data/node-v6.16.0-linux-x64/bin/cnpm  /usr/bin/cnpm

4、查看版本信息
cnpm -v

Maven

1、下载Maven
方式一:官网下载:http://maven.apache.org/download.cgi
方式二:wget Maven下载地址
wget http://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz(清华大学开源软件镜像服务)
wget http://mirror.bit.edu.cn/apache/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz(北京理工大学开源软件镜像服务)

2、解压tar包到/usr/local/
tar -zxvf apache-maven-3.3.9-bin.tar.gz  -C /usr/local/

3、配置环境变量,编辑/etc/profile文件,在/etc/profile文件末尾增加以下配置:vim /etc/profile
export MAVEN_HOME=/usr/local/apache-maven-3.3.9
export PATH=$MAVEN_HOME/bin:$PATH

4、使用source命令立即生效,刷新环境变量
source /etc/profile

5、查看版本信息
mvn -version

JDK

1、下载JDK:https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

2、解压tar包到/usr/local/目录下
tar zxvf jdk1.8.0_201.tar.gz -C /usr/local/

3、配置环境变量,编辑/etc/profile文件,在/etc/profile文件末尾增加以下配置:vim /etc/profile
export JAVA_HOME=/usr/local/jdk1.8.0_201
export PATH=${JAVA_HOME}/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

4、使用source命令立即生效,刷新环境变量
source /etc/profile

5、检验JDK是否安装成功,注:-version,不是--version
java -version 或者 javac

6、踩坑
如果出现这-bash: /usr/local/java/jdk1.8.0_171/bin/java: /lib/ld-linux.so.2: bad ELF interpreter: No such file问题
运行这个命令解决:sudo yum install glibc.i686

Nginx

0、前提
安装依赖包
yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel

1、下载nginx
方式一:官网下载:http://nginx.org/en/download.html
方式二:wget http://nginx.org/download/nginx-1.13.7.tar.gz

2、解压tar包到/usr/local/nginx/目录下
tar -zxvf nginx-1.13.7.tar.gz -C /usr/local/ngnix/

3、安装nginx
cd /usr/local/nginx/nginx-1.13.7
执行配置
./configure
编译安装
make && make install

4、配置nginx.conf,将端口号改成8089,因为可能apeache占用80端口,apeache端口尽量不要修改,选择修改nginx端口
vim /usr/local/nginx/nginx-1.13.7/conf/nginx.con

5、启动nginx
cd /usr/local/nginx/sbin/nginx/nginx-1.13.7
./nginx 启动
./nginx -s stop 关闭
./nginx -s reload 重启

6、查看nginx进程是否启动
ps -ef | grep nginx

7、验证nginx是否配置成功
nginx -t

8、查询nginx的安装路径
whereis nginx

2、编写前置脚本

#!/bin/bash

#app_build.sh

app_name=${1}                   #项目名称,例:Learn-Java
group_name=${2}                 #分组名称,例:best
env_name=${3}                   #环境名称,例:test1
time=`date +%Y-%m-%d_%H:%M:%S`  #时间

#检测前端编译是否成功
shell_check(){
    if [ $? -eq 0 ];then
        echo -e "33[32m${time} ===前端编译成功,继续===33[0m"
    else
        echo -e "33[31m${time} ===前端编译失败,请排查问题再发布===33[0m"
        exit 1
    fi
}

if [[ ${env_name} = "请选择" ]] ; then
    echo -e "33[31m${time} 请选择正确环境!33[0m"
    exit 1
elif [[ ${env_name} = "test1" || ${env_name} = "test2" ]] ; then
    echo -e "33[32m${time} ${group_name} ${app_name} ${env_name}  前端编译 cnpm install33[0m"
    cd /jenkins_workspace/${group_name}_${app_name}/${app_name}-view/
    cnpm install
    echo -e "33[32m${time} ${group_name} ${app_name} ${env_name}33[0m"
    npm run build:test1
    shell_check
    echo -e "33[32m${time} cp /jenkins_workspace/deploy.sh to /jenkins_workspace/${group_name}_${app_name}33[0m"
    cp /jenkins_workspace/deploy.sh  /jenkins_workspace/${group_name}_${app_name}
else
    echo -e "33[31m${time} 请输入正确参数!33[0m"
fi

3、编写应用部署脚本

#!/bin/bash

#deploy.sh

app_name=${1}                   #项目名称,例:Learn-Java
env_name=${3}                   #环境名称,例:test1
time=`date +%Y-%m-%d_%H:%M:%S`  #时间

#检查上一条命令是否执行成功
shell_check(){
    if [ $? -eq 0 ];then
        echo -e "33[32m${time} 2|8、上一条命令执行成功, 继续33[0m"
    else
echo -e "33[31m${time} 2|8、上一条命令执行失败, 退出33[0m"
        exit 1
    fi
}

#部署应用服务
deploy_app(){
    echo -e "33[32m${time} 1、解压${app_name}.tar.gz33[0m"
    cd /tmp/${app_name}/target/ && tar -xzvf ${app_name}.tar.gz

    shell_check

    echo -e "33[32m${time} 3、停止${app_name}服务33[0m"
    var=`cd /app/${app_name}/bin/ && su ${app_name} stop.sh`
    if [[ $var = *alive* ]];then
        echo -e "33[31m${time} $var 无法正常停止应用进程,请前往服务器进行排查33[0m"
        exit 1
    else
        echo -e "33[32m${time} $var ,继续33[0m"
    fi

    echo -e "33[32m${time} 4、覆盖代码33[0m"
    rsync -r  /tmp/${app_name}/target/conf/ /app/${app_name}/config
    rsync -r --delete /tmp/${app_name}/target/lib/ /app/${app_name}/lib

    echo -e "33[32m${time} 5、拉取disconf33[0m"
    cd /app/${app_name}/config && wget -O configs.tar.gz http://disconf.demo.com/api/config/downConfigs?app=${app_name}'&'env_name=${env_name}'&'version=1.0.0 && tar -xvf configs.tar.gz && rm -rf configs.tar.gz

    echo -e "33[32m${time} 6、分组赋权33[0m"
    cd /app && chown -R ${app_name}:coreapp ${app_name}

    echo -e "33[32m${time} 7、重启服务33[0m"
    cd /app/${app_name}/bin/ && su ${app_name} start.sh

    shell_check

    pid=`ps aux | grep ${app_name} | grep -v grep | awk '{print $2}'`
    if [ "${pid}" ]; then
        echo -e "33[32m${time} 9、${app_name} core ${pid} 启动成功33[0m"
    else
        echo -e "33[31m${time} 9、${app_name} core ${pid} 启动失败33[0m"
        exit 1
    fi

    echo -e "33[32m${time} 10、查看日志33[0m"
    cd /app/${app_name}/log/ && tail -n 200 stdout.log

    echo -e "33[32m${time} 11、删除/tmp目录下旧压缩包,避免再次部署代码重复33[0m"
    cd /tmp && rm -rf ${app_name}
}

deploy_app

4、Jenkins配置

指路【Jenkins系列】如何构建Jenkins Job。

新增Job,主要用于拉取代码,执行Maven编译,执行app_build.sh,将压缩包通过ssh发送到目标机器,远程调用目标机器的deploy.sh。

三、含泪踩坑

踩坑1

问题描述:在错误的路径拉取配置,原因是未成功解压压缩包。

解决方案:校验压缩包是否解压成功解压成功,并且在cd到正确的路径后添加&&(&&表示上一条命令执行成功再执行下一条命令)才进行拉取配置。

踩坑2

问题描述:项目没有正常停止,导致无法重新启动。

解决方案:虽然执行kill -9,但是未找到根本原因,因此加了一个检测机制,如果检测没有正常停止服务,则退出程序。

踩坑3

问题描述:生产部署脚本拉取了开发环境的的jdbc配置,原因是生产部署脚本写错了开发环境disconf的域名,当时我同时在搞开发生产环境的脚本,开发和生产是两套不同的脚本,一时混乱写错了,吓得一批,好在当时生产环境还没投产使用。

解决方案:为了避免后续这种情况的发生,而且是必须避免的,我们通过环境名称来判断走开发还是生产域名,这样就能保证脚本一致性了。

在这个项目实际遇到的问题远不止上面这几个,在这个实践过程中,我对整个应用部署流程有了更深的理解,平时方方面面的学习终于集中化起来进行实践了。

我习惯将学到的知识和遇到的问题记录起来,在写这篇文章的过程回过头来看,五味杂陈,原来我都经历了这些哈哈哈…

踩过的坑终究使我更加强大**,带你见证呱呱本呱成长为参天大呱~**

四、历史文章指路

关注【嘎嘎软件测试】

搞测试,不迷路

呱呱大王本呱带你飞!

嘎嘎软件测试

将分享个人成长、团队管理、软件测试技能知识等内容,更新频率一周两篇,做到有思想、有观点、有深度,欢迎订阅。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/732126.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号