自动化部署懒人系列之基础篇
背景:
作为一个运维方面还算可以的小白,很自然部门中关于一些运维,部署,监控的任务就落到我身上。在被小伙伴们无数次的呼唤解决项目部署问题后,我忍无可忍,所以,我的目标是把他们交给我的部
署任务完美的退回去,即使他们对Linux一无所知。
解决的问题:
频繁的部署,重启任务。
主要项目描述:
项目总有13个模块,spring boot 项目,启动模块有10个。
前提:
主管项目后台模块架构设计,参与大部分开发任务,使平台提供运维支持成为可能。由于项目在 不断扩展期间,所以,部署工作十分繁重,严重浪费了我的时间。
达到目标:
1. 通过sh run.sh module env 启动项目
2. 通过 sh shutdown.sh module env 停掉项目
3. 通过sh run_all.sh env 启动所有项目
4. 通过 sh shutdown_all.sh module env 停掉项目
5. 通过 sh clear.sh 清理服务器上七天以前的日志文件以及备份jar包
技术支持:
scp 执行文件上传
ssh 远程执行本地脚本文件
项目架构规范(针对运维部分)
1. 项目提供dev,uat,www环境的文件配置
2. spring boot 项目maven管理
3. 配置文件必须在模块目录下conf中application-env.properties
4. 启动端口必须配置在配置文件中
5. 模块打包为 Project_module.jar
6. 模块名字规范: Project_module
远程执行脚本
1. run_script.sh(远程启动脚本)
通过端口杀掉进程,通过模块名启动模块。
#! /bin/bash
echo $1,$2,$3
cd ~/ITS_service/$2/
pwd
pid=`/usr/sbin/lsof -t -i:$3`
echo $pid
if [ $pid != "" ]
then
kill -9 $pid
sleep 3
nohup java -jar ITS_$1.jar &
else
echo "端口不存在。。。。。。。。"
nohup java -jar ITS_$1.jar &
fi
2. shutdown_script.sh(远程停止脚本)
通过端口杀掉进程。
#!/usr/bin/env bash
pid=`/usr/sbin/lsof -t -i:$1`
echo $pid
if [ $pid != "" ]
then
exec kill -9 $pid
echo "---------------进程已关闭----------------"
else
echo "端口不存在。。。。。。。。"
fi
3. clear_script.sh(远程清理脚本)
清理任务清理所有。
#!/bin/bash
# 要清理的目录,多个目录用空格分开
logs=(/home/tomcat/ITS_service/www/logs /home/tomcat/ITS_service/dev/logs /home/tomcat/ITS_service/uat/logs)
# 循环 logs 数组
for dir in ${logs[*]}
do
# 删除目录下 7 天之前的日志文件
find $dir -mtime +7 -name *.log* | xargs rm
done
# 要清理的目录,多个目录用空格分开
jars=(/home/tomcat/ITS_service/www /home/tomcat/ITS_service/dev /home/tomcat/ITS_service/uat)
# 循环 jars 数组
for dir in ${jars[*]}
do
# 删除目录下 7 天之前的备份jar包
find $dir -mtime +7 -name backup* | xargs rm -rf
done
4. backup_script.sh(备份jar包)
通过 模块环境,模块名字备份jar。
#! /bin/bash
echo $1,$2
cd ~/ITS_service/$2/
pwd
t=`date "+%Y-%m-%d-%H"`
Ddate=`date "+%Y-%m-%d"`
folder=~/ITS_service/$2/backup_$Ddate/
echo "备份ITS_$1.jar.............."
if [ ! -d "$folder" ]; then
mkdir -p "$folder"
fi
cp ITS_$1.jar $folder/ITS_$1_backup_$t.jar
本地执行脚本
1. run.sh
通过模块名字环境名字打包,获取端口,通过调用(backup_script.sh)备份jar包,通过上传命令上传jar,通过调用启动远程脚本(run_script.sh)启动。
#!/usr/bin/env bash
#cd ./ITS_core
#mvn clean && mvn install -Dmaven.test.skip=true
#cd ..
#cd ./ITS_sdk
#mvn clean && mvn install -Dmaven.test.skip=true
#cd ..
#cd ./ITS_context
#mvn clean && mvn install -Dmaven.test.skip=true
#cd ..
cd ./ITS_$1
port=`cat ./src/main/resources/config/application-$2.properties | grep server.port | awk -F '=' '{print $2}'`
echo "port:${port}"
mvn clean
mvn package -P$2 -Dmaven.test.skip=true
cd target
DEV=dev
WWW=www
UAT=uat
DEV_HOST=`cat ../../host.properties | grep dev.host | awk -F '=' '{print $2}'`
UAT_HOST=`cat ../../host.properties | grep uat.host | awk -F '=' '{print $2}'`
WWW_HOST=`cat ../../host.properties | grep www.host | awk -F '=' '{print $2}'`
echo "----------------开始执行$2环境$1项目的部署-------------------------"
if [ "$2" == ${DEV} ]
then
OLD_IFS="$IFS"
IFS=","
arr=($DEV_HOST)
IFS="$OLD_IFS"
for host in ${arr[@]}
do
echo "-----------当前运维的机器ip是:$host--------------------"
echo "Please input y or n "
read
if [ "$REPLY" == "y" ]
then
ssh -C tomcat@$host "bash -s" < ../../backup_script.sh $1 $2
scp ITS_$1.jar tomcat@$host:/home/tomcat/ITS_service/$2/ITS_$1.jar
ssh -C tomcat@$host "bash -s" < ../../run_script.sh $1 $2 ${port}
else
echo "。。。。。。。。。"
fi
done
fi
if [ "$2" == ${WWW} ]
then
OLD_IFS="$IFS"
IFS=","
arr=($WWW_HOST)
IFS="$OLD_IFS"
for host in ${arr[@]}
do
echo "-----------当前运维的机器ip是:$host--------------------"
echo "Please input y or n "
read
if [ "$REPLY" == "y" ]
then
ssh -C tomcat@$host "bash -s" < ../../backup_script.sh $1 $2
scp ITS_$1.jar tomcat@$host:/home/tomcat/ITS_service/$2/ITS_$1.jar
ssh -C tomcat@$host "bash -s" < ../../run_script.sh $1 $2 ${port}
else
echo "。。。。。。。。。"
fi
done
fi
if [ "$2" == ${UAT} ]
then
OLD_IFS="$IFS"
IFS=","
arr=($UAT_HOST)
IFS="$OLD_IFS"
for host in ${arr[@]}
do
echo "-------------------当前运维的机器ip是:$host--------------------"
echo "Please input y or n "
read
if [ "$REPLY" == "y" ]
then
ssh -C tomcat@$host "bash -s" < ../../backup_script.sh $1 $2
scp ITS_$1.jar tomcat@$host:/home/tomcat/ITS_service/$2/ITS_$1.jar
ssh -C tomcat@$host "bash -s" < ../../run_script.sh $1 $2 ${port}
else
echo "。。。。。。。。。"
fi
done
fi
2. run_uninstall.sh
和上面不通是只进行启动不上传。
#!/usr/bin/env bash
cd ./ITS_$1
port=`cat ./src/main/resources/config/application-$2.properties | grep server.port | awk -F '=' '{print $2}'`
echo "port:${port}"
DEV=dev
WWW=www
UAT=uat
echo "-------------------------开始执行$2环境$1项目的部署-------------------------"
cd ..
DEV_HOST=`cat ./host.properties | grep dev.host | awk -F '=' '{print $2}'`
UAT_HOST=`cat ./host.properties | grep uat.host | awk -F '=' '{print $2}'`
WWW_HOST=`cat ./host.properties | grep www.host | awk -F '=' '{print $2}'`
if [ "$2" == ${DEV} ]
then
OLD_IFS="$IFS"
IFS=","
arr=($DEV_HOST)
IFS="$OLD_IFS"
for host in ${arr[@]}
do
echo "-----------当前运维的机器ip是:$host--------------------"
echo "Please input y or n "
read
if [ "$REPLY" == "y" ]
then
ssh -C tomcat@$host "bash -s" < ./run_script.sh $1 $2 ${port}
else
echo "。。。。。。。。。"
fi
done
fi
if [ "$2" == ${WWW} ]
then
OLD_IFS="$IFS"
IFS=","
arr=($WWW_HOST)
IFS="$OLD_IFS"
for host in ${arr[@]}
do
echo "-----------当前运维的机器ip是:$host--------------------"
echo "Please input y or n "
read
if [ "$REPLY" == "y" ]
then
ssh -C tomcat@$host "bash -s" < ./run_script.sh $1 $2 ${port}
else
echo "。。。。。。。。。"
fi
done
fi
if [ "$2" == ${UAT} ]
then
OLD_IFS="$IFS"
IFS=","
arr=($UAT_HOST)
IFS="$OLD_IFS"
for host in ${arr[@]}
do
echo "-----------当前运维的机器ip是:$host--------------------"
echo "Please input y or n "
read
if [ "$REPLY" == "y" ]
then
ssh -C tomcat@$host "bash -s" < ./run_script.sh $1 $2 ${port}
else
echo "。。。。。。。。。"
fi
done
fi
3. shutwon.sh
通过模块名字环境名字打包,获取端口,通过调用停止远程脚本(shutdown_script.sh)结束任务。
#!/usr/bin/env bash
cd ./ITS_$1
port=`cat ./src/main/resources/config/application-$2.properties | grep server.port | awk -F '=' '{print $2}'`
echo "-----------------当前项目端口号:${port}-----------------------"
echo "----------------开始执行$2环境$1项目下线-------------------------"
cd ..
DEV_HOST=`cat ./host.properties | grep dev.host | awk -F '=' '{print $2}'`
UAT_HOST=`cat ./host.properties | grep uat.host | awk -F '=' '{print $2}'`
WWW_HOST=`cat ./host.properties | grep www.host | awk -F '=' '{print $2}'`
if [ "$2"=="dev" ]
then
OLD_IFS="$IFS"
IFS=","
arr=($DEV_HOST)
IFS="$OLD_IFS"
for host in ${arr[@]}
do
echo "-----------当前运维的机器ip是:$host--------------------"
echo "Please input y nor n. "
read
if [ "$REPLY" == "y" ]
then
ssh tomcat@$host -C "bash -s" < ./stop_script.sh ${port}
else
echo "。。。。。。。。。"
fi
done
fi
if [ "$2" == "www" ]
then
OLD_IFS="$IFS"
IFS=","
arr=($WWW_HOST)
IFS="$OLD_IFS"
for host in ${arr[@]}
do
echo "-----------当前运维的机器ip是:$host--------------------"
echo "Please input y nor n. "
read
if [ "$REPLY" == "y" ]
then
ssh tomcat@$host -C "bash -s" < ./stop_script.sh ${port}
else
echo "。。。。。。。。。"
fi
done
fi
if [ "$2" == "uat" ]
then
OLD_IFS="$IFS"
IFS=","
arr=($UAT_HOST)
IFS="$OLD_IFS"
for host in ${arr[@]}
do
echo "-----------当前运维的机器ip是:$host--------------------"
echo "Please input y or n "
read
if [ "$REPLY" == "y" ]
then
ssh tomcat@$host -C "bash -s" < ./stop_script.sh ${port}
else
echo "。。。。。。。。。"
fi
done
fi
4. clear.sh
通过服务器列表调用清理脚本(clear_script.sh)清理任务
#!/bin/bash
DEV_HOST=`cat ./host.properties | grep dev.host | awk -F '=' '{print $2}'`
UAT_HOST=`cat ./host.properties | grep uat.host | awk -F '=' '{print $2}'`
WWW_HOST=`cat ./host.properties | grep www.host | awk -F '=' '{print $2}'`
HOST="$DEV_HOST,$UAT_HOST,$WWW_HOST"
OLD_IFS="$IFS"
IFS=","
arr=($HOST)
IFS="$OLD_IFS"
a_len=${#arr[@]}
for((count=0;count<a_len;count++))
do
index=$a_len
for((i=0;i<count;i++))
do
if [ ${arr[i]} == ${arr[count]} ]
then
index=$i
break;
fi
done
if [ $index -ge $a_len ]
then
echo "-----------当前清理的机器ip是:$host--------------------"
ssh -C tomcat@${arr[count]} "bash -s" < ./clear_script.sh
echo "-----------当前清理任务完成----------------------------"
fi
done
5. run_all.sh
通过host配置文件获取对应环境的host机器并调用run_uninstall.sh批量启动。
#! /bin/bash
CONTEXT=context
CODE=core
SDK=sdk
for module in `sed -n 's/.*>\(.*\)<\/module>/\1/p' $1 pom.xml`
do
fstr=`echo $module | cut -d \_ -f 2`
if [ "$fstr" == ${CONTEXT} ]
then
continue;
elif [ "$fstr" == ${CODE} ]
then
continue;
elif [ "$fstr" == ${SDK} ]
then
continue;
else
echo "开启项目-------$fstr----------"
sh run_uninstall.sh $fstr $1
fi
done
6. shutdown_all.sh
通过host配置文件获取对应环境的host机器并调用shutdown.sh批量结束。
#! /bin/bash
CONTEXT=context
CODE=core
SDK=sdk
for module in `sed -n 's/.*>\(.*\)<\/module>/\1/p' $1 pom.xml`
do
fstr=`echo $module | cut -d \_ -f 2`
if [ "$fstr" == ${CONTEXT} ]
then
continue;
elif [ "$fstr" == ${CODE} ]
then
continue;
elif [ "$fstr" == ${SDK} ]
then
continue;
else
sh shutdown.sh $fstr $1
fi
done
综上:
以上所有脚本文件需要放在项目根目录下执行。
总结:
优点:
可以通过简单的命令就可以启动,停止项目,使用方便。
不再需要登录到服务器上部署。
通过简单的说明,就可以使小伙伴们在自己机器实现部署。
缺点:
如果服务器实现环境隔离就无法通过ssh部署。
没有权限控制,很容易搞乱环境。开放性太高。
在杀掉进程时候有时候发现一个端口对应多个进程,情况无法停止。
启动时候可能只需要获取启动时候成功,不需要输出日志文件。
下篇将结合gitlab如何实现自动化部署,解决环境隔离问题
posted on 2017-05-31 20:21 LittlePony 阅读(6803) 评论(0) 编辑 收藏 举报