这里记录一个用shell语言实现的服务器资源监控并实现简单的负载均衡的实例小脚本。
实现功能的前置条件是需要做到跨服务器免密登录。
#!/bin/bash
help() {
echo "
######批次项目下机后,负载均衡分配到各台服务器######
Usage:
bash this_script <input.txt>
必填<input.txt> 输入文件,包括两列:第一列是run.sh文件的绝对路径,
第二列是给此项目赋予的cost等级。
cost等级说明:项目分为A、B、C、D、E以及S级;
A-E分别是资源消耗从高到低的等级秩,S级是特别加急的项目,会最优先分配。
S级项目有:加急项目、样本量过大的项目
A级项目有:MGS-AQ、WGS、WTS、WGBS
B级项目有:WES、Target、
C级项目有:STR、微生物、HLA、ATAC
D级项目有:Methylation、STR
"
}
if [[ $# -lt 1 ]] || [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then
help
exit 1
fi
Input_data=$1
#获取服务器的空闲Cpu、可用Memery。tr用于删除尾部多余的隐藏字符,方便存储。
function get_server_info(){
server=$1
Cpu_idle=$(ssh $server -tt " sar 1 5 |tail -1 |gawk '{print \$NF}'|tr -d '\r\n' ")
Mem_available=$(ssh $server -tt " free -h |grep 'Mem' |gawk '{print \$NF}'|sed 's/G$//'|tr -d '\r\n' ")
echo -e "${Cpu_idle}"
echo -e "${Mem_available}"
}
#定义使用到的服务器IP
SERVERS=(
"192.168.0.3"
"192.168.0.5"
"192.168.0.6"
"192.168.0.7"
)
#声明关联数组aggregate用于存放所有服务器剩余资源的统计结果
declare -A aggregate_Cpu
declare -A aggregate_Mem
#循环获取服务器info
for server in ${SERVERS[@]};
do
summary=($(get_server_info ${server}))
echo "服务器${server}Cpu资源剩余情况(%)->${summary[0]}"
echo "服务器${server}Mem资源剩余情况(G)->${summary[1]}"
aggregate_Cpu["${server}"]=${summary[0]}
aggregate_Mem["${server}"]=${summary[1]}
done
#按照服务器内存对服务器排序,方便后面轮询使用的时候从内存最大的服务器开始使用。
sort_Mem=(
$(
for IP in ${!aggregate_Mem[@]}
do
echo "${IP}:${aggregate_Mem[${IP}]}"
done |sort -t : -k 2 -r
)
)
echo -e "#################\n按照内存剩余量轮询服务器的顺序:"
for i in ${sort_Mem[@]}
do
echo ${i}
done
if [ ! -e $Input_data ]
then
echo "ERROR:不存在 $Input_data 文件,请检查。"
exit
fi
#全部项目按照等级归类
S_project=();
A_project=();
B_project=();
C_project=();
D_project=();
while read line
do
array=(${line})
if [ ${#array[@]} -ne 2 ]
then
echo "输入文件格式不对!请检查。";exit
fi
if [ ${array[1]} == "S" ]
then
S_project+=(${array[0]})
elif [ ${array[1]} == "A" ]
then
A_project+=(${array[0]})
elif [ ${array[1]} == "B" ]
then
B_project+=(${array[0]})
elif [ ${array[1]} == "C" ]
then
C_project+=(${array[0]})
elif [ ${array[1]} == "D" ]
then
D_project+=(${array[0]})
else
echo "项目cost等级错误!请检查。";exit
fi
done < $Input_data
#每个cost等级项目统计
echo -e "#################\n按照项目等级轮询的任务顺序:"
echo "S级项目:${S_project[@]}"
echo "A级项目:${A_project[@]}"
echo "B级项目:${B_project[@]}"
echo "C级项目:${C_project[@]}"
echo "D级项目:${D_project[@]}"
echo -e "#################\n"
SORT_project=(${S_project[@]} ${A_project[@]} ${B_project[@]} ${C_project[@]} ${D_project[@]})
for id in ${!SORT_project[@]}
do
serverIndex=$[ ${id} % ${#sort_Mem[@]} ]
serverID=${sort_Mem[${serverIndex}]%:*}
if [ ! -e ${SORT_project[${id}]} ]
then
echo "ERROR:不存在 ${SORT_project[${id}]} 文件,请检查。"
continue
fi
Tmpowner=$(ls -l ${SORT_project[${id}]} |gawk '{print $3}')
echo "${Tmpowner} ${serverID} ${SORT_project[${id}]} "
# ssh ${Tmpowner}@${serverID} -tt " nohup bash ${SORT_project[${id}]} & ;exit"
done
脚本前半部分实现服务器资源统计,后半部分是根据服务器资源统计的结果对输入安排到各个服务器上。