Linux 解决数量庞大wildfly容器启动与停止的脚本
一、问题
因公司业务的发展,后台架构的变更,导致测试环境(Linux)部署与管理困难成倍增长,duang的一下,增加N倍。进入正题说问题:
问题1. 测试环境包含普通用户环境、开发者用户环境,原来只需2个Wildfly,现需要15*2,30个容器,启动、停止、部署工作量巨大。
app appInterface battle friend gexin msg online passport pay push support union upload webInterface webView注:因公司以及其他原因,本文中的模块名、环境、数量都进行了适当的修改,此处只举例说明。
问题2. 后续模块扩展与容器增减维护工作
问题3. 部署包SVN的自动获取,自动部署
问题4. 部署完毕邮件通知
二、分析
1. 现状
a. SVN源码无权限,有固定目录取转测模块WAR包,但需要根据转测svn版本号取(最新的不一定是部署时转测的模块)
b. 转测模块不定,也许15个,也许2、3个
c. 15个模块(即15个WAR包),两环境(普通用户、开发者用户),需要30个容器
d. 根据转测模块,只需要停止对应模块所在容器,无须所有模块停止与启动
2. 分析与方案确定
1) 弃用Jenkins
a.无须自动构建:公司其他原因,测试无法获得SVN源码权限进行自动构建,Jenkins的自动化部署。
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.本想与自动部署一起写此文,发现所讲的内容与贴出的脚本内容过多,有时间再讲讲解决第三、四个问题,超简单的实现方式shell脚本。
4.Jenkins大多数觉得持续集成用这个很叼,完了其引入除了用发邮件功能、定时任务,其他组件基本用不上。很多人也许只是对Jenkins组件的熟悉,但完全不具备Jenkins转化提升效率的能力,维护成本与效率还不如之前手工操作。
5.思想的支撑尤为重要,可以在有限的资源里发挥出最大的功效,寻找到最优的方案。
切勿舍本求末,忘记初心!
如转载还请保留出处与作者姓名Findyou,谢谢!
Linux 解决数量庞大wildfly容器启动与停止的脚本的更多相关文章
- linux 程序启动与停止管理脚本
公司接了一个第三方的系统,基于linux写的几个程序,一共有9个部件,第三方没有给脚本,每次启动或停止都得一个一个手工去停止或修改.......,这里稍微鄙视下. 没办法,求人还不如自己动手写, 需求 ...
- linux系统下apache服务的启动、停止、重启命令
本文章简单的介绍了关于linux下在利用命令来操作apache的基本操作如启动.停止.重启等操作,对入门者不错的选择.本文假设你的apahce安装目录为 usr local apache2,这些方法适 ...
- Linux下安装nginx,以及启动和停止
1.安装 安装nginx之前,首先确保系统已经安装了依赖:g++.gcc.openssl-devel.pcre-devel和zlib-devel软件 yum install gcc-c++ yum - ...
- linux系统下nginx/mysql/php启动、停止、重启命令
/usr/local/nginx/sbin/nginx /etc/init.d/mysql start /usr/local/php/sbin/php-fpm start #nginx命令 ...
- Atitit. 软件GUI按钮与仪表盘--web服务器区--获取apache配置文件路径 linux and apache的启动、停止、重启
Atitit. 软件GUI按钮与仪表盘--web服务器区--获取apache配置文件路径 linux and apache的启动.停止.重启 可以通过"netstat -anp" ...
- Atitit. 软件GUIbutton与仪表盘--webserver区--获取apache配置文件路径 linux and apache的启动、停止、重新启动
Atitit. 软件GUIbutton与仪表盘--webserver区--获取apache配置文件路径 linux and apache的启动.停止.重新启动 能够通过"netstat ...
- Dubbo应用启动与停止脚本,超具体解析
本周刚好研究了一下dubbo的启动脚本,所以在官网的启动脚本和公司内部的启动脚本做了一个整理,弄了一份比較通过的Dubbo应用启动和停止脚本. 以下的脚本仅仅应用于配置分离的应用.什 ...
- 一键启动NameNode和DataNode--shell脚本
使用shell脚本,一键启动hadoop中的NameNode和DataNode.分为普通版和装逼版.装逼版较普通版多了很多判断和信息提示,当然主要还是为了我联系shell脚本而写的. 如果想实现复用, ...
- Centos7.3_x86_64通过systemctl控制tomcat8.0.46启动和停止
Centos7.3_x86_64通过systemctl控制tomcat8..46启动和停止 之前在centos 6上通过脚本控制tomcat 启动和停止的脚本,虽然在centos 7也可以使用,但ce ...
随机推荐
- MVVM模式解析和在WPF中的实现(三)命令绑定
MVVM模式解析和在WPF中的实现(三) 命令绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...
- 很多人很想知道怎么扫一扫二维码就能打开网站,就能添加联系人,就能链接wifi,今天说下这些格式,明天做个demo
有些功能部分手机不能使用,网站,通讯录,wifi基本上每个手机都可以使用. 在看之前你可以扫一扫下面几个二维码先看看效果: 1.二维码生成 网址 (URL) 包含网址的 二维码生成 是大家平时最常接触 ...
- 【C#代码实战】群蚁算法理论与实践全攻略——旅行商等路径优化问题的新方法
若干年前读研的时候,学院有一个教授,专门做群蚁算法的,很厉害,偶尔了解了一点点.感觉也是生物智能的一个体现,和遗传算法.神经网络有异曲同工之妙.只不过当时没有实际需求学习,所以没去研究.最近有一个这样 ...
- 如何避免git每次提交都输入密码
在ubuntu系统中,如何避免git每次提交都输入用户名和密码?操作步聚如下:1: cd 回车: 进入当前用户目录下:2: vim .git-credentials (如果没有安装vim 用其它编辑器 ...
- SDWebImage源码解读之SDWebImageCache(上)
第五篇 前言 本篇主要讲解图片缓存类的知识,虽然只涉及了图片方面的缓存的设计,但思想同样适用于别的方面的设计.在架构上来说,缓存算是存储设计的一部分.我们把各种不同的存储内容按照功能进行切割后,图片缓 ...
- Java FtpClient 实现文件上传服务
一.Ubuntu 安装 Vsftpd 服务 1.安装 sudo apt-get install vsftpd 2.添加用户(uftp) sudo useradd -d /home/uftp -s /b ...
- [开发笔记]yum错误
yum 错误TypeError: rpmdb open failed 解决办法 是因为RPM数据库出现损坏导致的,它导致所有的软件的升级.安装甚至是删除都会出现问题,终端出现乱码,YUMEX也用不成, ...
- Kooboo CMS技术文档之四:Kooboo CMS的站点组成部分
Kooboo CMS本着功能独立分离的原则,将站点分为三部分组成:用户管理,站点管理和内容数据库管理.各个功能之间既可独立使用,也可以容易组成在一起形成一个完整的系统. 用户管理 管理整个系统内的用户 ...
- Java类访问权限修饰符
一.概要 通过了解Java4种修饰符访问权限,能够进一步完善程序类,合理规划权限的范围,这样才能减少漏洞.提高安全性.具备表达力便于使用. 二.权限表 修饰符 同一个类 同一个包 不同包的子类 不同包 ...
- openresty 前端开发入门四之Redis篇
这章主要演示怎么通过lua连接redis,并根据用户输入的key从redis获取value,并返回给用户 操作redis主要用到了lua-resty-redis库,代码可以在github上找得到 而且 ...