632 lines
24 KiB
Bash
632 lines
24 KiB
Bash
|
|
#!/bin/bash
|
|||
|
|
# ---------------------------------------------------------
|
|||
|
|
# 开发工具脚本
|
|||
|
|
# @author whjing2012@gmail.com
|
|||
|
|
# ---------------------------------------------------------
|
|||
|
|
# set -f
|
|||
|
|
# 语言版本 zh-CN
|
|||
|
|
la="zh-CN"
|
|||
|
|
# 打包目录
|
|||
|
|
release_dir="/data/yhdl/release"
|
|||
|
|
# 代码目录
|
|||
|
|
server_dir="/data/yhdl/server"
|
|||
|
|
# 控制服数据库
|
|||
|
|
db_host='10.154.234.243'
|
|||
|
|
db_port=3306
|
|||
|
|
db_name="oms"
|
|||
|
|
db_user='xge'
|
|||
|
|
db_pass="HrsmjzIhKWff1Iae"
|
|||
|
|
db_conn="mysql -h$db_host -P$db_port -u$db_user -p$db_pass -D$db_name "
|
|||
|
|
# 产品ID
|
|||
|
|
product_id=1
|
|||
|
|
# 服务器状态[0:正常 1:注销 2:主合服 3:被合服]
|
|||
|
|
srv_status='0,2'
|
|||
|
|
# 版本号
|
|||
|
|
ver="v170929"
|
|||
|
|
# 是否本地启动节点热更 当hotswap=true | false 时适用
|
|||
|
|
# true 本地开节点操作
|
|||
|
|
# false 相应服上开节点操作
|
|||
|
|
local_node="false"
|
|||
|
|
# 是否执行热更 true | false | mysql | gen_ctl | update_cfg | check | start | stop
|
|||
|
|
# true 执行热更操作
|
|||
|
|
# false 不执行热更操作
|
|||
|
|
# mysql 执行数据库脚本
|
|||
|
|
# gen_ctl 重新生成ctl.sh脚本
|
|||
|
|
# update_cfg 更新配置文件
|
|||
|
|
# update_cfg_sql 更新配置文件和SQL数据结构
|
|||
|
|
# check 检查节点是否已停止运行(挂掉了)
|
|||
|
|
# check_start 检查节点是否完成启动
|
|||
|
|
# start 启动节点
|
|||
|
|
# stop 停止节点
|
|||
|
|
# ver 版本更新
|
|||
|
|
# open 开入口
|
|||
|
|
# close 关入口
|
|||
|
|
# dellog 删除日志
|
|||
|
|
hotswap="true"
|
|||
|
|
# 热更新最大重试次数
|
|||
|
|
hotswap_max=5
|
|||
|
|
# 最大启动进程数 同时执行多个命令
|
|||
|
|
pro_max=10
|
|||
|
|
|
|||
|
|
# 物理服务器 可指定部分 上传版本至所有物理服务器用 all 或是列举出所有 建议用 all
|
|||
|
|
mac_list=( 9996 )
|
|||
|
|
mac_list=( 9996 10001 10002 )
|
|||
|
|
# mac_list=all
|
|||
|
|
# mac_list="all" # 上传更新代码到所有物理机
|
|||
|
|
|
|||
|
|
# 踢除指定物理服务器 在mac_list="all"时起作用 多个用,分隔 如 kick_mac="'10001','10002'"
|
|||
|
|
kick_mac="'0'"
|
|||
|
|
# kick_mac="'9999'"
|
|||
|
|
|
|||
|
|
# 操作指定节点 可指定部分 全部为 all 或列举出所有 建议用 all
|
|||
|
|
# 服务器列表 格式:平台,区号
|
|||
|
|
zone_list=(
|
|||
|
|
"release,1"
|
|||
|
|
"center,0"
|
|||
|
|
# "sytest,1"
|
|||
|
|
# "sytest,6"
|
|||
|
|
# "sytest,2"
|
|||
|
|
# "sytest,3"
|
|||
|
|
# "sytest,4"
|
|||
|
|
# "center,1"
|
|||
|
|
)
|
|||
|
|
# zone_list="'fzone','gzone','hzone'" # 更新指定平台,用'单引号包括 多个用;分号分隔 如 zone_list="'4399','37'"
|
|||
|
|
# zone_list="'sytest'" # 更新所有指定版本${ver}的服
|
|||
|
|
# zone_list="all" # 更新所有指定版本${ver}的服
|
|||
|
|
|
|||
|
|
# 踢除指定平台 在zone_list="all"时起作用 每个平台用'单引号包括 多个用,分隔 如 kick_platform="'4399','37'"
|
|||
|
|
kick_platform="'verify'"
|
|||
|
|
# kick_platform="'fsgj_center'"
|
|||
|
|
|
|||
|
|
# 踢除服 格式:kick_zone_list=( "4399,1" "4399,2" )
|
|||
|
|
kick_zone_list=( )
|
|||
|
|
# kick_zone_list=( "release,1" "center,0" )
|
|||
|
|
|
|||
|
|
# 附加选服
|
|||
|
|
ext_zone_sql=''
|
|||
|
|
# ext_zone_sql="and c.name='hzone' and zone_id >= 1 and zone_id <= 35"
|
|||
|
|
|
|||
|
|
# 需要执行的方法操作 格式:mod:fun:args
|
|||
|
|
exec_list=(
|
|||
|
|
# "info:i:[]"
|
|||
|
|
# "keyword:reload:[]"
|
|||
|
|
# "holiday_mgr:reload:[]"
|
|||
|
|
# "holiday_role:reload:[all]"
|
|||
|
|
# sys_env:del:[rank_match_dynamic_robot]
|
|||
|
|
# mail:check_gmail:[701]
|
|||
|
|
# guild_dun:loald:[]
|
|||
|
|
# holiday_fix:holiday_compensated_mail:[]
|
|||
|
|
# "say_subtitle:clear:[lists#seq(201,203)]"
|
|||
|
|
# "say_subtitle:clear:[lists#seq(401,410)]"
|
|||
|
|
# "dun_trial_mgr:check_replay:[]"
|
|||
|
|
# 'code_util:eval:["A=5,B=3,A*B."]'
|
|||
|
|
# "charge_mgr:sync_charge_log:[10]"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 需要额外上传的文件
|
|||
|
|
ufile_list=(
|
|||
|
|
# "/data/amp_web.sql:/data/"
|
|||
|
|
# "/data/yhdl/server/ebin/item_gift_data.beam:/data/huanxiang_code/v150729/server/ebin/"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# 需要执行的sql
|
|||
|
|
exec_sql=(
|
|||
|
|
# "source /data/huanxiang_code/$ver/server/tpl/ver_db.sql"
|
|||
|
|
# "select count(*) from role"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
# 更新脚本目标
|
|||
|
|
filepath=$(cd `dirname $0`; pwd)
|
|||
|
|
|
|||
|
|
# 执行文件输出文件夹
|
|||
|
|
code_out_dir=$(pwd)"/out_code_update_tmp"
|
|||
|
|
mkdir -p ${code_out_dir}
|
|||
|
|
chmod +x ${code_out_dir}
|
|||
|
|
|
|||
|
|
# 执行出错的语句
|
|||
|
|
exe_err=${code_out_dir}"/err_code_update.log"
|
|||
|
|
|
|||
|
|
# 执行出错的服
|
|||
|
|
exe_err_zone=${code_out_dir}"/tmp_last_err_zone.txt"
|
|||
|
|
|
|||
|
|
# 最后一次执行的所有命令
|
|||
|
|
all_exe_cmd=${code_out_dir}"/all_exe_cmd_tmp.sh"
|
|||
|
|
|
|||
|
|
# 执行结果输出
|
|||
|
|
exe_result_out=${code_out_dir}"/result_out.log"
|
|||
|
|
|
|||
|
|
# 缓存脚本目录
|
|||
|
|
sh_tmp_dir=$filepath/sh/tmp
|
|||
|
|
|
|||
|
|
# 命令计数器
|
|||
|
|
idx=1
|
|||
|
|
|
|||
|
|
# 执行相应操作
|
|||
|
|
fun_exec(){
|
|||
|
|
if [ "$do" = "fdo" ] && [ "$zone_idx" != "" ] ; then
|
|||
|
|
shtmp=$sh_tmp_dir/sh_$((zone_idx%pro_max)).sh
|
|||
|
|
if [ -f $shtmp ]; then
|
|||
|
|
echo "ret=\$($exestr)" >> $shtmp
|
|||
|
|
else
|
|||
|
|
echo "ret=\$($exestr)" > $shtmp
|
|||
|
|
fi
|
|||
|
|
echo "echo -e \"${idx}.${exestr}\n$(fun_time)[\e[91m${platform},${zone_id}\e[0;0m]执行结果:==\${ret}\"" >> $shtmp
|
|||
|
|
return
|
|||
|
|
fi
|
|||
|
|
# sleep $((random%10+1))
|
|||
|
|
echo -e "$idx.$exestr"
|
|||
|
|
echo -e $exestr >> ${all_exe_cmd}
|
|||
|
|
exe_cmd=$exestr
|
|||
|
|
if [ "${do}" = "do" ] || [ "$do" = "fdo" ]; then
|
|||
|
|
for((i=1; i<=$hotswap_max; i=i+1)); do
|
|||
|
|
ret=$(eval $exe_cmd)
|
|||
|
|
echo -e "${idx}.${exestr}\n$(fun_time)[\e[91m${platform},${zone_id}\e[0;0m]执行结果:==${ret}"
|
|||
|
|
if [ $(echo ${ret} | grep "节点还在正常运行中" | wc -l) -gt 0 ]; then
|
|||
|
|
echo "${platform},${zone_id}" >> ${exe_err_zone}
|
|||
|
|
[ "${platform}" != '' -a "${zone_id}" != '' ] && echo "[${platform}_${zone_id}]==error==>[${ret}]" >> ${exe_result_out}
|
|||
|
|
break
|
|||
|
|
elif [ $(echo ${ret} | grep "main" | grep -e "(error|terminating|无法访问节点)" | grep "hotswap" | wc -l) -gt 0 ] && [ $(echo ${ret} | grep "return:{badrpc,nodedown}" | wc -l) -gt 0 ]; then
|
|||
|
|
if [ $hotswap_max -gt $i ]; then
|
|||
|
|
echo "$(fun_time)[${platform},${zone_id}]服热更和语句执行出错,重新执行"
|
|||
|
|
elif [ "$hotswap" != "stop" ]; then
|
|||
|
|
echo "${exestr}" >> ${exe_err}
|
|||
|
|
echo "\"${platform},${zone_id}\"" >> ${exe_err_zone}
|
|||
|
|
fi
|
|||
|
|
elif [ $(echo ${ret} | grep "main" | grep "error|terminating|无法访问节点" | grep "hotswap" | wc -l) -gt 0 ]; then
|
|||
|
|
if [ $hotswap_max -gt $i ]; then
|
|||
|
|
exestr=${exestr//ctl.sh exec/ctl.sh nodo} ## 防止重复执行
|
|||
|
|
echo "$(fun_time)[${platform},${zone_id}]服热更出错,重新执行"
|
|||
|
|
elif [ "$hotswap" != "stop" ]; then
|
|||
|
|
echo "${exestr}" >> ${exe_err}
|
|||
|
|
echo "\"${platform},${zone_id}\"" >> ${exe_err_zone}
|
|||
|
|
fi
|
|||
|
|
elif [ $(echo ${ret} | grep "return:{badrpc,nodedown}" | wc -l) -gt 0 ]; then
|
|||
|
|
if [ $hotswap_max -gt $i ]; then
|
|||
|
|
exestr=${exestr//ctl.sh hotswap/ctl.sh nodo} ## 防止重复执行
|
|||
|
|
echo "$(fun_time)[${platform},${zone_id}]服执行语句出错,重新执行"
|
|||
|
|
elif [ "$hotswap" != "stop" ]; then
|
|||
|
|
echo "${exestr}" >> ${exe_err}
|
|||
|
|
echo "\"${platform},${zone_id}\"" >> ${exe_err_zone}
|
|||
|
|
fi
|
|||
|
|
elif [ $(echo ${ret} | grep -e "(error|terminating)" | wc -l) -gt 0 ]; then
|
|||
|
|
if [ $hotswap_max -gt $i ]; then
|
|||
|
|
echo "$(fun_time)[${platform},${zone_id}]服热更和语句执行出错,重新执行"
|
|||
|
|
elif [ "$hotswap" != "stop" ]; then
|
|||
|
|
echo "${exestr}" >> ${exe_err}
|
|||
|
|
echo "\"${platform},${zone_id}\"" >> ${exe_err_zone}
|
|||
|
|
fi
|
|||
|
|
else
|
|||
|
|
[ "${platform}" != '' -a "${zone_id}" != '' ] && echo "[${platform}_${zone_id}]====>[${ret}]" >> ${exe_result_out}
|
|||
|
|
break
|
|||
|
|
fi
|
|||
|
|
done
|
|||
|
|
fi
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 开启后台执行方式
|
|||
|
|
fun_exec_pro(){
|
|||
|
|
if [ ${pro_max} -gt 1 ] && [ "$do" != "sdo" ] ; then
|
|||
|
|
fun_exec &
|
|||
|
|
fun_idx
|
|||
|
|
else
|
|||
|
|
fun_exec
|
|||
|
|
fi
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 提示是否继续
|
|||
|
|
fun_alert(){
|
|||
|
|
echo "是否继续(y/n)"
|
|||
|
|
read ret
|
|||
|
|
case $ret in
|
|||
|
|
y|y|yes|yes) ;;
|
|||
|
|
*)
|
|||
|
|
exit 0
|
|||
|
|
;;
|
|||
|
|
esac
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 获取当前最大版本号
|
|||
|
|
fun_max_ver(){
|
|||
|
|
cd ${release_dir}
|
|||
|
|
maxver=""
|
|||
|
|
for filename in $(ls); do
|
|||
|
|
if [ -d "${filename}" ] && [ "${filename:0:3}" = "${ver:0:3}" ] && [[ "${filename}" > "${maxver}" ]]; then
|
|||
|
|
# echo ${filename}
|
|||
|
|
maxver=${filename}
|
|||
|
|
fi
|
|||
|
|
done
|
|||
|
|
echo "当前最大版本号: ${maxver}"
|
|||
|
|
if [ "${maxver}" != "${ver}" ]; then
|
|||
|
|
echo -e "注意===============[当前热更版本( \e[91m${ver}\e[0;0m )与最大版本号( \e[91m${maxver}\e[0;0m )不一致,请确认]==========================="
|
|||
|
|
fi
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 热更操作
|
|||
|
|
fun_update(){
|
|||
|
|
do=${1}
|
|||
|
|
|
|||
|
|
echo "准备热更版本: ${ver}"
|
|||
|
|
fun_max_ver
|
|||
|
|
fun_get_all_machine
|
|||
|
|
fun_get_all_zone
|
|||
|
|
|
|||
|
|
zone_list=( $(echo "==${zone_list[*]}==" | sed 's/\(\s\+\)/==\1==/g') )
|
|||
|
|
# echo -e "将更新节点[数量:$(fun_color 92 ${#zone_list[@]})]:( ${zone_list[@]} )"
|
|||
|
|
for s in ${kick_zone_list[@]}; do
|
|||
|
|
zone_list=( ${zone_list[*]//==${s}==/} ) ## 踢除指定服
|
|||
|
|
done
|
|||
|
|
zone_list=( ${zone_list[*]//==/} ) ## 踢除附加符号
|
|||
|
|
|
|||
|
|
start_time=$(date +%s)
|
|||
|
|
echo -e "将更新节点[数量:$(fun_color 92 ${#zone_list[@]})]:( ${zone_list[@]} )"
|
|||
|
|
echo -e "代码将上传到物理机[数量:$(fun_color 92 ${#mac_list[@]})]:( ${mac_list[@]} )"
|
|||
|
|
echo "踢除平台信息:${kick_platform}"
|
|||
|
|
echo -e "踢除节点[数量:$(fun_color 92 ${#kick_zone_list[@]})]:( ${kick_zone_list[@]} )"
|
|||
|
|
|
|||
|
|
if [ "${do}" = "do" ] || [ "$do" = "fdo" ]; then
|
|||
|
|
fun_alert
|
|||
|
|
fi
|
|||
|
|
echo "" > ${exe_err}
|
|||
|
|
echo "" > ${exe_err_zone}
|
|||
|
|
echo "" > ${all_exe_cmd}
|
|||
|
|
echo "" > ${exe_result_out}
|
|||
|
|
rm ${sh_tmp_dir} -rf
|
|||
|
|
mkdir -p ${sh_tmp_dir}
|
|||
|
|
chmod +x ${all_exe_cmd}
|
|||
|
|
|
|||
|
|
cd ${server_dir}
|
|||
|
|
echo "$(fun_time)开始上传代码到物理服务器..."
|
|||
|
|
for m in ${mac_list[@]}; do
|
|||
|
|
exestr="./srv.sh srv code_update ${m} ${ver}"
|
|||
|
|
fun_exec_pro
|
|||
|
|
for f in ${ufile_list[@]}; do
|
|||
|
|
sfile=$(echo ${f} | cut -d':' -f1)
|
|||
|
|
tfile=$(echo ${f} | cut -d':' -f2)
|
|||
|
|
exestr="fun_upload_file ${m} ${sfile} ${tfile}"
|
|||
|
|
fun_exec_pro
|
|||
|
|
done
|
|||
|
|
done
|
|||
|
|
wait
|
|||
|
|
do_start_time=$(date +%s)
|
|||
|
|
idx=1
|
|||
|
|
|
|||
|
|
echo "$(fun_time)开始执行更新等脚本操作..."
|
|||
|
|
init_zone_list=( ${zone_list[@]} )
|
|||
|
|
for((x=1; x<=$hotswap_max; x=x+1)); do
|
|||
|
|
fun_update_zone $@
|
|||
|
|
fail_zone_list=( $(cat $exe_err_zone|grep ",") )
|
|||
|
|
if [ "$hotswap" = "stop" ] && [ ${#fail_zone_list[@]} -gt 0 ]; then
|
|||
|
|
echo -e "更新失败需要重新执行节点[数量:$(fun_color 92 ${#fail_zone_list[@]})]:( ${fail_zone_list[@]} )"
|
|||
|
|
pro_max=1
|
|||
|
|
zone_list=( ${fail_zone_list[@]} )
|
|||
|
|
echo "" > ${exe_err_zone}
|
|||
|
|
fun_alert
|
|||
|
|
continue
|
|||
|
|
else
|
|||
|
|
break
|
|||
|
|
fi
|
|||
|
|
done
|
|||
|
|
|
|||
|
|
echo -e "代码将上传到物理机[数量:$(fun_color 92 ${#mac_list[@]})]"
|
|||
|
|
echo -e "更新服务器[数量:$(fun_color 92 ${#init_zone_list[@]})]"
|
|||
|
|
echo -e "更新失败节点[数量:$(fun_color 92 ${#fail_zone_list[@]})]:( ${fail_zone_list[@]} )"
|
|||
|
|
echo -e "上传代码到物理机总耗时(秒):\e[91m$(expr $do_start_time - $start_time)"
|
|||
|
|
echo -e "执行热更命令操作总耗时(秒):\e[91m$(expr `date +%s` - $do_start_time)"
|
|||
|
|
echo -e "全部操作过程累计总耗时(秒):\e[91m$(expr `date +%s` - $start_time)"
|
|||
|
|
if [ $( cat ${exe_err} | grep -v '^$' | wc -l) -gt 0 ]; then
|
|||
|
|
echo -e "$(fun_time)所有执行出错语句===========> $(cat ${exe_err} | grep -v '^$' | wc -l)\n$(cat ${exe_err})"
|
|||
|
|
fi
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
fun_update_zone(){
|
|||
|
|
zone_idx=0
|
|||
|
|
for s in ${zone_list[@]}; do
|
|||
|
|
let zone_idx=$zone_idx+1
|
|||
|
|
if [ "${do}" = "show" ] && [ ${zone_idx} -eq 2 ] && [ ${#zone_list[@]} -gt 50 ]; then
|
|||
|
|
fun_alert
|
|||
|
|
fi
|
|||
|
|
platform=$(echo ${s} | cut -d',' -f1)
|
|||
|
|
zone_id=$(echo ${s} | cut -d',' -f2)
|
|||
|
|
eval "$(fun_main_srv_info $platform $zone_id)"
|
|||
|
|
if [ "${hotswap}" != "ver" ] && [ "${ver}" != "${row['ver']}" ]; then
|
|||
|
|
echo -e "$(fun_color 91 'error>>') [错误]( $(fun_color 91 ${platform},${zone_id}) )服版本号[ $(fun_color 91 ${row['ver']} ) ]对不上热更版本号[ $(fun_color 91 ${ver} ) ], 不进行该操作"
|
|||
|
|
continue
|
|||
|
|
fi
|
|||
|
|
exestr=""
|
|||
|
|
if [ "${hotswap}" = "update_cfg" ]; then
|
|||
|
|
exestr="./srv.sh srv gen_ctl ${platform} ${zone_id} && " # 更新指定服的脚本文件
|
|||
|
|
elif [ "${hotswap}" = "update_cfg_sql" ]; then
|
|||
|
|
exestr="./srv.sh srv gen_ctl ${platform} ${zone_id} && " # 更新指定服的脚本文件
|
|||
|
|
elif [ "${hotswap}" = "gen_ctl" ]; then
|
|||
|
|
exestr="./srv.sh srv gen_ctl ${platform} ${zone_id}" # 更新指定服的脚本文件
|
|||
|
|
fun_exec_pro
|
|||
|
|
continue
|
|||
|
|
elif [ "${hotswap}" = "ver" ]; then
|
|||
|
|
exestr="$db_conn -e \"update zones set ver='$2', is_maintain=$3 where product_id=$product_id and zone_id=${zone_id} and platform_id in (select platform_id from platforms where product_id=$product_id and name='${platform}')\"" # 更新指定服的脚本文件
|
|||
|
|
fun_exec_pro
|
|||
|
|
continue
|
|||
|
|
elif [ "${hotswap}" = "close" ]; then
|
|||
|
|
exestr="$db_conn -e \"update zones set is_maintain=1 where product_id=$product_id and zone_id=${zone_id} and platform_id in (select platform_id from platforms where product_id=$product_id and name='${platform}')\"" # 更新指定服的脚本文件
|
|||
|
|
fun_exec_pro
|
|||
|
|
continue
|
|||
|
|
elif [ "${hotswap}" = "open" ]; then
|
|||
|
|
exestr="$db_conn -e \"update zones set is_maintain=0 where product_id=$product_id and zone_id=${zone_id} and platform_id in (select platform_id from platforms where product_id=$product_id and name='${platform}')\"" # 更新指定服的脚本文件
|
|||
|
|
fun_exec_pro
|
|||
|
|
continue
|
|||
|
|
elif [ "${local_node}" = "true" ]; then
|
|||
|
|
fun_update_local_node
|
|||
|
|
continue
|
|||
|
|
fi
|
|||
|
|
ssh="ssh -p${row['ssh_port']} ${row['ssh_user']}@${row['ip']}"
|
|||
|
|
do_sql
|
|||
|
|
exestr="${exestr}${ssh} 'cd ${row['root']}"
|
|||
|
|
if [ "${hotswap}" = "true" ]; then
|
|||
|
|
exestr="${exestr} && ./ctl.sh hotswap 1"
|
|||
|
|
elif [ "${hotswap}" = "update_cfg" ]; then
|
|||
|
|
exestr="${exestr} && ./ctl.sh update_cfg"
|
|||
|
|
elif [ "${hotswap}" = "update_cfg_sql" ]; then
|
|||
|
|
exestr="${exestr} && ./ctl.sh update_cfg"
|
|||
|
|
exestr="${exestr} && mysql -uroot -p\$(cat /data/save/mysql_root) -D${row['db_name']} -e \"source /data/huanxiang_code/$ver/server/tpl/ver_db.sql\""
|
|||
|
|
elif [ "${hotswap}" = "start" ]; then
|
|||
|
|
exestr="${exestr} && ./ctl.sh start"
|
|||
|
|
elif [ "${hotswap}" = "dellog" ]; then
|
|||
|
|
exestr="${exestr} && echo \"\" > screenlog.0"
|
|||
|
|
elif [ "${hotswap}" = "stop" ]; then
|
|||
|
|
exestr="${exestr} && ./ctl.sh stop"
|
|||
|
|
exestr="${exestr} && [ \$(screen -ls|grep \"${row['nodename']}\"|wc -l) -eq 0 ] || echo -e \e[91m服务器[${platform}_${zone_id}]已关服失败\e[0;0m "
|
|||
|
|
elif [ "${hotswap}" = "check" ]; then
|
|||
|
|
exestr="${exestr} && [ \$(screen -ls|grep \"${row['nodename']}\"|wc -l) -eq 0 ] && echo 服务器[${platform}_${zone_id}]已停止运行"
|
|||
|
|
elif [ "${hotswap}" = "check_start" ]; then
|
|||
|
|
exestr="${exestr} && [ \$(./ctl.sh exec services:check:[]|grep not_start_ok|wc -l) -gt 0 ] && echo 服务器[${platform}_${zone_id}]未完全启动运行"
|
|||
|
|
elif [ "${hotswap}" = "mysql" ]; then
|
|||
|
|
continue
|
|||
|
|
fi
|
|||
|
|
for fun in ${exec_list[@]}; do
|
|||
|
|
exestr="${exestr} && ./ctl.sh exec \"${fun//\"/\\\"}\""
|
|||
|
|
done
|
|||
|
|
exestr="${exestr}'"
|
|||
|
|
fun_exec_pro
|
|||
|
|
done
|
|||
|
|
|
|||
|
|
if [ "$do" = "fdo" ]; then
|
|||
|
|
chmod +x $sh_tmp_dir/*.sh
|
|||
|
|
for tmpsh in $(ls ${sh_tmp_dir}); do
|
|||
|
|
echo "exec_sh_file===>$tmpsh"
|
|||
|
|
$sh_tmp_dir/$tmpsh &
|
|||
|
|
done
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
wait
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 采用本地节点热更
|
|||
|
|
fun_update_local_node(){
|
|||
|
|
nodename=${row['nodename']}
|
|||
|
|
fun_cmd="io:format(\\\"[\e[92mdev:u()\e[0;0m]return:~w~n\\\", [rpc:call('${nodename}', dev, u, [])])"
|
|||
|
|
for cmd_line in ${exec_list[@]}; do
|
|||
|
|
mod=$(echo $cmd_line | cut -d':' -f1)
|
|||
|
|
fun=$(echo $cmd_line | cut -d':' -f2)
|
|||
|
|
args=$(echo $cmd_line | cut -d':' -f3)
|
|||
|
|
if [[ $(echo $mod | grep "^[a-z_]\{1,50\}$") = "" ]]; then
|
|||
|
|
echo ">> [错误]模块名格式不正常:\e[91m${mod}\e[0;0m"
|
|||
|
|
exit 1
|
|||
|
|
fi
|
|||
|
|
if [[ $(echo $fun | grep "^[a-z_]\{1,50\}$") = "" ]]; then
|
|||
|
|
echo ">> [错误]方法名格式不正常:\e[91m${fun}\e[0;0m"
|
|||
|
|
exit 1
|
|||
|
|
fi
|
|||
|
|
if [[ $(echo $args | grep "^\[.*\]$") = "" ]]; then
|
|||
|
|
echo -e ">> [错误]方法参数格式不正常:\e[91m${args}\e[0;0m"
|
|||
|
|
exit 1
|
|||
|
|
fi
|
|||
|
|
fun_cmd="${fun_cmd}, io:format(\\\"\e[92mapply(${mod}, ${fun}, ${args//\"/\\\\\\\"})\e[0;0mreturn:~w~n\\\", [rpc:call('${nodename}', ${mod}, ${fun}, ${args//\"/\\\"})])"
|
|||
|
|
done
|
|||
|
|
|
|||
|
|
exestr="erl -noshell -kernel inet_dist_listen_min 40100 -kernel inet_dist_listen_max 44000 -hidden -pa ${server_dir}/ebin -name update_${nodename} -setcookie ${row['cookie']} -eval \"io:setopts([{encoding,unicode}]), ${fun_cmd}\" -s c q"
|
|||
|
|
fun_exec_pro
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 数据库执行
|
|||
|
|
do_sql(){
|
|||
|
|
IFS=$'\n'
|
|||
|
|
exestr_bak=$exestr
|
|||
|
|
for sql in ${exec_sql[@]}; do
|
|||
|
|
sql=${sql//\'/\\\"}
|
|||
|
|
exestr="${ssh} 'mysql -uroot -p\$(cat /data/save/mysql_root) -D${row['db_name']} -e \"${sql}\"'"
|
|||
|
|
fun_exec_pro
|
|||
|
|
done
|
|||
|
|
exestr=$exestr_bak
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 获取服务器安装信息
|
|||
|
|
fun_srv_info(){
|
|||
|
|
platform=$1
|
|||
|
|
zone_id=$2
|
|||
|
|
if [ "" = "${platform}" ] || [ "" = "${zone_id}" ]; then
|
|||
|
|
echo "error>> [错误]没有输入有效的平台标识和区号"
|
|||
|
|
exit 1
|
|||
|
|
fi
|
|||
|
|
eval "$(mysql_get_row "select a.name product_name, b.name platform, c.is_maintain, c.ver, d.cookie, d.db_name, d.root, d.zone_id, e.name machine, e.code_path, e.ip, e.ssh_port, e.ssh_user from products a, platforms b, zones c, nodes d, machines e where a.product_id = $product_id and a.product_id = b.product_id and b.platform_id = c.platform_id and b.platform_id = d.platform_id and c.zone_id = d.zone_id and d.machine_id = e.machine_id and b.name='${platform}' and c.zone_id=${zone_id}")"
|
|||
|
|
declare -p row
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 获取合服主服务器安装信息
|
|||
|
|
fun_main_srv_info(){
|
|||
|
|
platform=$1
|
|||
|
|
zone_id=$2
|
|||
|
|
if [ "" = "${platform}" ] || [ "" = "${zone_id}" ]; then
|
|||
|
|
echo "error>> [错误]没有输入有效的平台标识和区号"
|
|||
|
|
exit 1
|
|||
|
|
fi
|
|||
|
|
eval "$(mysql_get_row "select a.name product_name, b.name platform, c.ver, c.is_maintain, d.cookie, d.db_name, d.root, d.zone_id, e.name machine, e.code_path, e.ip, e.ssh_port, e.ssh_user from products a, platforms b, zones c, nodes d, machines e where a.product_id = $product_id and a.product_id = b.product_id and b.platform_id = c.platform_id and b.platform_id = d.platform_id and c.zone_id = d.zone_id and d.machine_id = e.machine_id and c.installed=1 and c.srv_status in ($srv_status) and ((b.name='${platform}' and c.zone_id=${zone_id}) or combine like '%<<__${platform}_${zone_id}__>>%')")"
|
|||
|
|
declare -p row
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# sql语句执行结果中的第一行
|
|||
|
|
# 返回的结果存放在$ROW变量中
|
|||
|
|
# 用法示例:
|
|||
|
|
# eval "$(mysql_get_row select * from mysql.user)"
|
|||
|
|
# for k in ${!row[@]}; do
|
|||
|
|
# echo $k = ${row[$k]}
|
|||
|
|
# done
|
|||
|
|
mysql_get_row(){
|
|||
|
|
#set names utf8;
|
|||
|
|
local sql="$@ limit 1 "
|
|||
|
|
IFS=$'\n'
|
|||
|
|
# local lines=( $(${db_conn} -ss -e"$sql\G") )
|
|||
|
|
local lines=( $(mysql -h$db_host -P$db_port -u$db_user -p$db_pass -D$db_name -ss -e"$sql\G") )
|
|||
|
|
lines=( ${lines[*]//\**/} ) # 删除分隔符
|
|||
|
|
lines=( ${lines[*]//:\ /\'\]=\"} ) # 替换等号
|
|||
|
|
lines=( ${lines[*]/#/tmp\[\'} ) # 替换变量名
|
|||
|
|
lines=( ${lines[*]/%/\"} ) # 增加尾部双引号
|
|||
|
|
declare -A tmp row
|
|||
|
|
eval "$(echo "${lines[*]}")" # 转成关联数组
|
|||
|
|
# 去除多余空格
|
|||
|
|
for k in ${!tmp[@]}; do
|
|||
|
|
row[${k/#* /}]=${tmp[$k]}
|
|||
|
|
done
|
|||
|
|
declare -p row
|
|||
|
|
}
|
|||
|
|
# 获取所有物理服务器ID列表
|
|||
|
|
fun_get_all_machine(){
|
|||
|
|
if [ "${mac_list}" = "all" ]; then
|
|||
|
|
mac_list=( $(${db_conn} -ss -e "select distinct m.name from machines as m, nodes as n, zones as z where m.product_id=$product_id and m.machine_id=n.machine_id and n.platform_id=z.platform_id and n.zone_id=z.zone_id and z.lang='${la}' and z.ver='${ver}' and m.name not in (${kick_mac}) order by m.name") )
|
|||
|
|
fi
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 获取所有服务信息
|
|||
|
|
fun_get_all_zone(){
|
|||
|
|
if [ "${zone_list}" = "all" ]; then
|
|||
|
|
zone_list=( $(${db_conn} -ss -e "select concat(p.name,',', z.zone_id) as a from zones z, platforms p where z.product_id=$product_id and z.platform_id=p.platform_id and lang='${la}' and ver='${ver}' and installed=1 and srv_status in ($srv_status) and p.name not in (${kick_platform}) ${ext_zone_sql} order by p.name, zone_id") )
|
|||
|
|
elif [ $(echo ${zone_list} | grep "'" | wc -l) -gt 0 ]; then
|
|||
|
|
zone_list=( $(${db_conn} -ss -e "select concat(p.name,',', zone_id) as a from zones z, platforms p where z.product_id=$product_id and z.platform_id=p.platform_id and ver='${ver}' and p.name in (${zone_list}) and installed=1 and srv_status in ($srv_status) ${ext_zone_sql} order by p.name, zone_id") )
|
|||
|
|
fi
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 上传文件
|
|||
|
|
fun_upload_file(){
|
|||
|
|
machine=$1
|
|||
|
|
source=$2
|
|||
|
|
target=$3
|
|||
|
|
eval "$(mysql_get_row "select * from machines where product_id=$product_id and name = '${machine}'")"
|
|||
|
|
scp -P${row['ssh_port']} $source ${row['ssh_user']}@${row['ip']}:${target}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 下载文件
|
|||
|
|
fun_download_file(){
|
|||
|
|
machine=$1
|
|||
|
|
source=$2
|
|||
|
|
target=$3
|
|||
|
|
eval "$(mysql_get_row "select * from machines where product_id=$product_id and name = '${machine}'")"
|
|||
|
|
scp -P${row['ssh_port']} ${row['ssh_user']}@${row['ip']}:${source} ${target}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 命令计数器
|
|||
|
|
fun_idx(){
|
|||
|
|
# echo "=============== $(jobs -l | wc -l)"
|
|||
|
|
if [ $((idx%pro_max)) -eq 0 ]; then
|
|||
|
|
echo "$(fun_time)正在批量执行命令,请等待=== 当前命令编号:$idx"
|
|||
|
|
fi
|
|||
|
|
let idx=$idx+1
|
|||
|
|
fun_wait_pro
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 暂停等待后台进程结束
|
|||
|
|
fun_wait_pro(){
|
|||
|
|
while [ $(jobs -l | wc -l) -ge $pro_max ]
|
|||
|
|
do
|
|||
|
|
sleep 0.1
|
|||
|
|
done
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 使用screen方式执行
|
|||
|
|
fun_screen_do(){
|
|||
|
|
path=${code_out_dir}
|
|||
|
|
tmp_file=$path/tmp_code_update.sh
|
|||
|
|
cat > ${tmp_file} <<EOF
|
|||
|
|
#!/bin/bash
|
|||
|
|
ulimit -SHn 102400
|
|||
|
|
${filepath}/code_update.sh do
|
|||
|
|
EOF
|
|||
|
|
chmod +x ${tmp_file}
|
|||
|
|
screen -dmSL update_zone_$la -s ${tmp_file}
|
|||
|
|
fun_shell
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 进入shell
|
|||
|
|
fun_shell(){
|
|||
|
|
screen -r update_zone_$la
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 时间
|
|||
|
|
fun_time(){
|
|||
|
|
echo $(date +">>##[%Y-%m-%d %H:%M:%S]")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 颜色
|
|||
|
|
fun_color(){
|
|||
|
|
echo "\e[$1m$2\e[0;0m"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 显示ssh登录指定服务器
|
|||
|
|
fun_ssh(){
|
|||
|
|
platform=$1
|
|||
|
|
zone_id=$2
|
|||
|
|
eval "$(fun_main_srv_info $platform $zone_id)"
|
|||
|
|
echo "ssh -p${row['ssh_port']} ${row['ssh_user']}@${row['ip']} # 主服目录:${row['root']}" # && cd ${row['root']}
|
|||
|
|
ssh -p${row['ssh_port']} ${row['ssh_user']}@${row['ip']} # && cd ${row['root']}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 下载文件
|
|||
|
|
fun_ssh_m(){
|
|||
|
|
machine=$1
|
|||
|
|
eval "$(mysql_get_row "select * from machines where product_id=$product_id and name = '${machine}'")"
|
|||
|
|
ssh -p${row['ssh_port']} ${row['ssh_user']}@${row['ip']}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 打包代码
|
|||
|
|
fun_pack(){
|
|||
|
|
./srv.sh srv pack_all $ver $1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
fun_main(){
|
|||
|
|
cmd=$1
|
|||
|
|
shift
|
|||
|
|
case $cmd in
|
|||
|
|
show) fun_update show $@;;
|
|||
|
|
do) fun_update do $@;;
|
|||
|
|
fdo) fun_update fdo $@;;
|
|||
|
|
sdo) fun_screen_do $@;;
|
|||
|
|
shell) fun_shell;;
|
|||
|
|
srv) fun_srv_info $@;;
|
|||
|
|
main) fun_main_srv_info $@;;
|
|||
|
|
mach) fun_get_all_machine && echo "==>>( ${mac_list} )";;
|
|||
|
|
srvs) fun_get_all_zone && echo "===>>( ${zone_list[*]} )";;
|
|||
|
|
ssh) fun_ssh $@;;
|
|||
|
|
ssh_m) fun_ssh_m $@;;
|
|||
|
|
ufile) fun_upload_file $@;;
|
|||
|
|
dfile) fun_download_file $@;;
|
|||
|
|
pack) fun_pack $@;;
|
|||
|
|
*)
|
|||
|
|
echo "show 显示即将执行的语句"
|
|||
|
|
# echo "do 执行更新操作"
|
|||
|
|
echo "sdo 用screen方式执行更新操作"
|
|||
|
|
echo "shell 进入screen查看执行情况"
|
|||
|
|
echo "ssh P Z 进入指定服务器"
|
|||
|
|
echo "srv P Z 查看指定服务器信息"
|
|||
|
|
echo "main P Z 查看指定服务器主合服信息"
|
|||
|
|
echo "ufile 10001 /data/test.txt /data/ 上传文件到指定目录"
|
|||
|
|
echo "dfile 10001 /data/fsgj_4399_1/env.cfg /data/card/ 下载文件到指定目录"
|
|||
|
|
echo "group GroupId Platform Z1 Z2 Z3 设置分组 Z1为主服"
|
|||
|
|
exit 1
|
|||
|
|
;;
|
|||
|
|
esac
|
|||
|
|
exit 0
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if [ "$undo" != 'true' ]; then
|
|||
|
|
fun_main $@
|
|||
|
|
fi
|
|||
|
|
|