因公司业务的发展,后台架构的变动,致使测试环境(Linux)部署与管理困难成倍增加,duang的一下,增长N倍。进入正题说问题:web
问题1. 测试环境包含普通用户环境、开发者用户环境,原来只需2个Wildfly,现须要15*2,30个容器,启动、中止、部署工做量巨大。shell
1 app
2 appInterface
3 battle
4 friend
5 gexin
6 msg
7 online
8 passport
9 pay
10 push
11 support
12 union
13 upload
14 webInterface
15 webView注:因公司以及其余缘由,本文中的模块名、环境、数量都进行了适当的修改,此处只举例说明。bash
问题2. 后续模块扩展与容器增减维护工做 架构
问题3. 部署包SVN的自动获取,自动部署app问题4. 部署完毕邮件通知
1. 现状
a. SVN源码无权限,有固定目录取转测模块WAR包,但须要根据转测svn版本号取(最新的不必定是部署时转测的模块)svn
b. 转测模块不定,也许15个,也许二、3个测试
c. 15个模块(即15个WAR包),两环境(普通用户、开发者用户),须要30个容器优化
d. 根据转测模块,只须要中止对应模块所在容器,无须全部模块中止与启动ui
2. 分析与方案肯定
1) 弃用Jenkins
a.无须自动构建:公司其余缘由,测试没法得到SVN源码权限进行自动构建,Jenkins的自动化部署。spa
b.不够灵活:WAR的自动化部署,Jenkins虽可部署,但须要15个Job+,总体转测时用1Job统一部署,如模块转测试则须要按每一个模块(每一个Job)一一点击
c.工做量未减小:研发转测发布固定目录是以svn版本号发布,在部署时已经可能最新的版本号是另外一个转测模块,所以须要取对应的版本号,每次改太麻烦,基本没有减小工做量。
2) 选用Shell脚本
a.脚本实现快速,随时修改
b.容器的操做都是Linux(shell)命令
c.自动化部署也采用shell分发与检测部署
d.邮件发送采用mail命令
1.wildfly统一命名规则
普通用户环境:Formal-wildfly-模块名
开发者环境:DEV-wildfly-模块名
Formal-wildfly-app
Formal-wildfly-appInterface
Formal-wildfly-battle
Formal-wildfly-friend
Formal-wildfly-gexin
...
DEV-wildfly-app
DEV-wildfly-appInterface
DEV-wildfly-battle
DEV-wildfly-friend
DEV-wildfly-gexin
...
2.模块名称列表: wildfly.list
app|app
appInterface|ae
battle|b
friend|f
gexin|g
msg|m
online|o
passport|pt
pay|pay
push|ph
support|st
union|un
upload|ud
webInterface|we
webView|ww注意:
a.第一列为模块名,用于检测wildfly容器,故须要严格注意大小写
b.第二列为启动、中止、检查脚本使用的参数缩写
c.后续扩展增长模块,只须要增长对应的容器,而后修改此文件加入模块名便可,此处解决第2个问题
3.启动Wildfly脚本(run_wildfly.sh)
# !/bin/bash
# Author:findyou
# Email:1968089885@qq.com
cDate=`date +%Y-%m-%d`
cTime=`date +%H:%M`
shellDIR= " /root/ shell/ "
wildfly_rootDir= " /data/ "
conf_file= " wildfly.list "
echo_tips= " "
checkBoolean=0
# 检测wildfly.list文件是否存在,不存在-则退出脚本执行
if [ ! -f ${shellDIR}${conf_file} ]; then
echo " Not Found : ${shellDIR}${conf_file} "
exit 1
fi
# 读wildfly.list文件
count_n=0
while read line;
do
count_n=`expr ${count_n} + 1` # 统计模块个数
wildfly[$count_n]=`echo $line|cut -d ' | ' -f 1` # 获到模块名称
wildfly_quick[$count_n]=`echo $line|cut -d ' | ' -f 2` # 得到快捷命令
done < ${shellDIR}${conf_file}
# 脚本帮助提示,并退出脚本
help_tips(){
echo " eg: $0 [wildflyName|a] "
echo ""
echo " wildflyName: "
for ((i=1; i<=${count_n}; i++));
do
echo " ${echo_tips}${wildfly[$i]}|${wildfly_quick[$i]} "
done
echo ""
exit 1
}
# 若是检测到没有传入参数,则执行help_tips方法,
if [ ! -n " $1 " ] ; then
help_tips
fi
# 将传入的 模块名称 参数赋值给para_cmd
para_cmd=$1
# 休眠方法,用于启动间隔
sleep_2(){
# echo "${echo_tips}${echo_tips}Sleep 2 second!"
sleep 2
}
# 循环启动Wildfly方法
run_wildfly(){
echo " Time : ${cDate} ${cTime} "
# 循环wildfly.list文件中的全部模块,根据传入参数,判断执行相应的启动
for ((i=1; i<=${count_n}; i++));
do
# 根据脚本传入的参数,启动对应的容器,传为a则启动全部容器。
if [ " ${para_cmd} " == " a " -o " ${para_cmd} " == " ${wildfly[$i]} " -o " ${para_cmd} " == " ${wildfly_quick[$i]} " ];then
echo " Start: ${wildfly[$i]} "
# 检查 普通用户 对应容器的进程
formal_pc=`ps -ef|grep " Formal-wildfly-${wildfly[$i]}/ "|grep -v grep|wc -l`
# 容器进程数,若是不为0,则说明已启动。反之则进行容器启动
if [ $formal_pc -ne 0 ] ; then
echo " ${echo_tips}${echo_tips}Failure: UAT is already running! "
else
echo " ${echo_tips}UAT Start.... "
# 进入对应的容器,启动容器
cd ${wildfly_rootDir}Formal-wildfly-${wildfly[$i]}/bin
nohup sh standalone.sh >/dev/null 2>&1 &
echo " ${echo_tips}Please Check file: ${wildfly_rootDir}Formal-wildfly-${wildfly[$i]}/standalone/log/server.log "
sleep_2
fi
# 检查 开发者用户 对应容器的进程
dev_pc=`ps -ef|grep " Dev-wildfly-${wildfly[$i]}/ "|grep -v grep|wc -l`
if [ $dev_pc -ne 0 ] ; then
echo " ${echo_tips}${echo_tips}Failure: UAT-DEV is already running! "
else
echo " ${echo_tips}UAT-DEV Start.... "
cd ${wildfly_rootDir}Dev-wildfly-${wildfly[$i]}/bin
nohup sh standalone.sh >/dev/null 2>&1 &
echo " ${echo_tips}Please Check file: ${wildfly_rootDir}Dev-wildfly-${wildfly[$i]}/standalone/log/server.log "
sleep_2
fi
# 记录启动模块数
checkBoolean=`expr ${checkBoolean} + 1`
fi
done
}
# 执行run_wildfly方法
run_wildfly
# 传入了参数,可是没有找到应的模块进行启动,调help_tips
if [ ${checkBoolean} -eq 0 ];then
help_tips
fi说明:
1.wildfly.list需要与run_wildfly.sh放在同一目录,脚本没有采用相对路径,故run_wildfly.sh脚本中须要调整对应的目录参数shellDIR
2.命令使用,如启动app容器: ./run_wildfly.sh app
3.启动全部app容器:./run_wildfly.sh a
4.检查Wildfly是否运行脚本(check_wildfly.sh)
脚本逻辑与启动脚本一致,直接替换掉run_wildfly方法便可,但记得调用修改后的方法
check_wildfly(){echo "Time : ${cDate} ${cTime}"
# 循环wildfly.list文件中的全部模块,根据传入参数,判断执行相应的启动
for ((i=1; i<=${count_n}; i++));
do
# 根据脚本传入的参数,启动对应的容器,传为a则启动全部容器。
if [ "${para_cmd}" == "a" -o "${para_cmd}" == "${wildfly[$i]}" -o "${para_cmd}" == "${wildfly_quick[$i]}" ];then
echo "Check: ${wildfly[$i]}"
#检查 普通用户 对应容器的进程
formal_pc=`ps -ef|grep "Formal-wildfly-${wildfly[$i]}/"|grep -v grep|wc -l`
#容器进程数,若是不为0,则说明已启动。反之则进行容器启动
if [ $formal_pc -eq 0 ] ; then
echo "${echo_tips}${echo_tips}UAT not Found!"
else
echo "${echo_tips}UAT is running!"
fi
#检查 开发者用户 对应容器的进程
dev_pc=`ps -ef|grep "Dev-wildfly-${wildfly[$i]}/"|grep -v grep|wc -l`
if [ $dev_pc -eq 0 ] ; then
echo "${echo_tips}${echo_tips}UAT-DEV not Found!"
else
echo "${echo_tips}UAT-DEV is running!"
fi
# 记录启动模块数
checkBoolean=`expr ${checkBoolean} + 1`
fi
done
}说明:
1.检查全部app容器运行状态:./check_wildfly.sh a
5.中止Wildfly脚本(stop_wildfly.sh)
脚本逻辑与启动脚本一致,直接替换掉run_wildfly方法便可,但记得调用修改后的方法
stop_wildfly(){
for ((i=1; i<=${count_n}; i++));
do
if [ " ${para_cmd} " == " a " -o " ${para_cmd} " == " ${wildfly[$i]} " -o " ${para_cmd} " == " ${wildfly_quick[$i]} " ];then
echo " Stop: ${wildfly[$i]} "
# 检查 普通用户 对应容器的进程,获得进程号
formal_pc=`ps -ef|grep " Formal-wildfly-${wildfly[$i]}/ "|grep -v grep|awk ' {print $2} '`
if [ " $formal_pc " == "" ] ; then
echo " ${echo_tips}${echo_tips}UAT not Found! "
else
# 中止进程
kill -9 $formal_pc
sleep_2
# 再次检测是否已中止进程
formal_pc1=`ps -ef|grep " Formal-wildfly-${wildfly[$i]}/ "|grep -v grep|awk ' {print $2} '`
if [ " $formal_pc1 " == "" ] ; then
echo " ${echo_tips}Stop UAT Success! "
else
echo " ${echo_tips}${echo_tips}Stop UAT Failure! "
fi
fi
# 检查 开发者用户 对应容器的进程,获得进程号
dev_pc=`ps -ef|grep " Dev-wildfly-${wildfly[$i]}/ "|grep -v grep|awk ' {print $2} '`
if [ " $dev_pc " == "" ] ; then
echo " ${echo_tips}${echo_tips}UAT-DEV not Found! "
else
# 中止进程
kill -9 $dev_pc
sleep_2
# 再次检测是否已中止进程
dev_pc1=`ps -ef|grep " Dev-wildfly-${wildfly[$i]}/ "|grep -v grep|awk ' {print $2} '`
if [ " $dev_pc1 " == "" ] ; then
echo " ${echo_tips}Stop UAT-DEV Success! "
else
echo " ${echo_tips}${echo_tips}Stop UAT-DEV Failure! "
fi
fi
checkBoolean=`expr ${checkBoolean} + 1`
fi
done
}说明:
1.中止全部容器:./stop_wildfly.sh a
至此,第1个问题已圆满解决!
结束语:
1.本来考虑与实现相对简单,初版,把全部的容器路径写到文件里,读取启动与中止便可,但不利于自动化部署、WAR分发等问题处理。
2.这个版本是实际当中优化的第三个版本,相对扩展与维护简单,为自动化部署提供中止与启动脚本,也最适合咱们目前的转测流程。
3.本想与自动部署一块儿写此文,发现所讲的内容与贴出的脚本内容过多,有时间再讲讲解决第3、四个问题,超简单的实现方式shell脚本。
4.Jenkins大多数以为持续集成用这个很叼,完了其引入除了用发邮件功能、定时任务,其余组件基本用不上。不少人也许只是对Jenkins组件的熟悉,但彻底不具有Jenkins转化提高效率的能力,维护成本与效率还不如以前手工操做。
5.思想的支撑尤其重要,能够在有限的资源里发挥出最大的功效,寻找到最优的方案。
切勿舍本求末,忘记初心!
如转载还请保留出处与做者姓名Findyou,谢谢!