假設一種情境,需要在多個節點需要執行相同命令(考慮命令的不確定性),一般使用for 迴圈,ssh直接調用。例:需要查看每個節點的根目錄使用方式:
實際上,僅僅需將上述幾行命令寫成一個指令碼,將要執行的命令設為位置參數,即可在一個互信的叢集內滿足這些要求了,看似問題得到瞭解決,筆者此前也的確是這麼做的,但是問題出現了,有些命令的執行過程漫長,而這種按順序執行的方法,在執行有些命令時,等待的時間絕對是讓人崩潰的,譬如:如果在成百上千個節點叢集內,為每個節點更新庫(yum update),或者產生yum緩衝(yum makecache),或者每個節點都是新的,裡面有好多磁碟需要格式化掛載,如果使用for迴圈按順序執行,相信我,格式化的磁碟的等待時間會讓你無法忍受的,如果這個任務還是在規定的時間必須完成的話.......
好吧,囉嗦半天,需求出現了,先思考要解決的問題,後有簡單的部分實現和測試
1、所有節點是互信的,通過安裝系統時實現(系統安裝階段實現)
2、所有節點可以使用常規的Regex取出對應的IP列表(指令碼實現)
3、必須已安裝screen包,通過調用這個命令實現近乎並發執行任務(指令碼實現)
4、命令執行結果的傳回值擷取,用以判斷是否成功執行(未實現)
5、screen的資源釋放問題(未實現)
6、考慮網路故障的錯誤處理(未實現)
7、考慮執行失敗的錯誤處理(未實現)
8、如果需要在每個節點執行的任務過多,可考慮將需要執行的任務寫成一個簡單的執行指令碼,做推送,並控制執行;4、5、6、7的實現可考慮此方法。
9、考慮遠程執行命令時環境變數的問題(未實現)
10、不足之處,歡迎補充:
代碼部分實現如下:
代碼環境如下:
系統為CentOS6.3 x86_64 均已安裝screen包和互信
在互信的節點將命令:yum makecache 分別在如下三個節點執行:
10.1.6.1 disk1.mos.com disk1
10.1.6.2 disk2.mos.com disk2
10.1.6.3 disk3.mos.com disk3
#!/bin/bashCMD=${1:-/usr/bin/yum makecache}CMD_SN="disk_ver.1"DATE="/bin/date +%k:%M:%S/%Y-%m-%d"SSH="/usr/bin/ssh -q -o StrictHostKeyChecking=no"SCREEN=/usr/bin/screenLIST=(`cat /etc/hosts|grep mos.com|awk '{print $1}'`)for i in ${LIST[@]};do $SSH $i $SCREEN -dmS $CMD_SN $SSH $i $SCREEN -S $CMD_SN -X screen $CMD echo -en "`$DATE` $i done.\n\n"done
查看本欄目更多精彩內容:http://www.bianceng.cnhttp://www.bianceng.cn/OS/Linux/
在三個節點分別放置一個簡單的指令碼,用來查看命令是否被成功執行,代碼如下:
#!/bin/bashDate="/bin/date +%k:%M:%S/%Y-%m-%d"Mlog=/var/log/mon.logTEE(){ /usr/bin/tee -a $Mlog}while :;do INFO=`ps aux|grep -v grep|grep yum` if [ -n "$INFO" ];then echo -en "`$Date` : $INFO \n\n" |TEE fi sleep 1done