zoukankan      html  css  js  c++  java
  • Linux 解决数量庞大wildfly容器启动与停止的脚本

    一、问题

    因公司业务的发展,后台架构的变更,导致测试环境(Linux)部署与管理困难成倍增长,duang的一下,增加N倍。进入正题说问题:

    问题1.  测试环境包含普通用户环境、开发者用户环境,原来只需2个Wildfly,现需要15*2,30个容器,启动、停止、部署工作量巨大

    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

    注:因公司以及其他原因,本文中的模块名、环境、数量都进行了适当的修改,此处只举例说明。

    问题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,谢谢! 

  • 相关阅读:
    Java Servlet(十):JSTL核心标签库
    Java Servlet(九):转发请求与重定向请求区别
    Java tomcat启动失败(Servlet3.0 Web Project):A child container failed during start
    快速安装服务
    Java Servlet(八):EL自定义函数
    Java Servlet(七):JavaWeb MVC 操作(jdk7+tomcat7+eclipse)
    新版mysql(mysql-5.7.12-winx64)安装
    oracle之 oradebug 命令用法
    Linux 绑定双网卡
    Linux 之 NTP 服务 服务器
  • 原文地址:https://www.cnblogs.com/findyou/p/5596233.html
Copyright © 2011-2022 走看看