用python的threading模塊寫了個部署腳本,使用中總遇到個奇怪問題。
先看python腳本中的threading方法:
#threading_cmd 方法
def threading_test(in_ip, dir_name, server):
semaphore.acquire()
ssh_cmd = "ssh root@%s 'echo %s'" %(in_ip, dir_name)
proc = subprocess.Popen(ssh_cmd, shell = True, stdout = subprocess.PIPE, stderr = subprocess.PIPE, stdin = subprocess.PIPE)
cmdout, cmderr = proc.communicate()
sys.stdout.write(cmdout)
#print "*** %s *** %s" %(cmdout, dir_name)
print "\033[1;31;40m########## %s 服 目錄: %s 重啟完畢! 結(jié)束時間: %s ##########\033[0m\n" %(server, dir_name, time.strftime('%H:%M:%S',time.localtime(time.time())))
semaphore.release()
再看如何調(diào)用的:
elif cmd == 'thread_cmd':
#run_cmd = sys.argv[3]
thread_num = 80
check = raw_input("\033[1;31;40m確認(rèn)要 并行 重啟 %s 嗎? 此次啟動線程數(shù)為 %d 個!\033[0m\n" %(zone, thread_num))
semaphore = threading.BoundedSemaphore(thread_num)
if check == 'yes':
print "\033[1;31;40m########## 重啟 %s 任務(wù)開始 啟動線程數(shù)為 %d 個! 開始時間: %s ##########\033[0m" %(zone, thread_num, time.strftime('%H:%M:%S',time.localtime(time.time())))
for server in sorted(do_server_list):
in_ip = in_ip_dict.get(server)
dir_name = dir_dict.get(server)
#t1=threading.Thread(target=threading_cmd, args=(in_ip,dir_name,server,run_cmd))
t1=threading.Thread(target=threading_test, args=(in_ip,dir_name,server))
t1.start()
else:
print "\033[1;31;40m退出 請重新確認(rèn)!\033[0m"
基本流程就是啟80個線程,每個線程去特定的ip,特定的目錄去執(zhí)行shell腳本
但是有時會遇到下圖中的情況,紅框中的那些沒有執(zhí)行直接就返回print的結(jié)果了

之后咨詢了公司里的python大拿,在threading方法里添加了print cmdout的語句。
#threading_cmd 方法
def threading_test(in_ip, dir_name, server):
semaphore.acquire()
ssh_cmd = "ssh root@%s 'echo %s'" %(in_ip, dir_name)
proc = subprocess.Popen(ssh_cmd, shell = True, stdout = subprocess.PIPE, stderr = subprocess.PIPE, stdin = subprocess.PIPE)
cmdout, cmderr = proc.communicate()
sys.stdout.write(cmdout)
print "*** %s *** %s" %(cmdout, dir_name) #<<<<<----- 添加了這句看回顯
print "\033[1;31;40m########## %s 服 目錄: %s 重啟完畢! 結(jié)束時間: %s ##########\033[0m\n" %(server, dir_name, time.strftime('%H:%M:%S',time.localtime(time.time())))
semaphore.release()
再執(zhí)行結(jié)果如下:

紅框中的幾個服確實(shí)是沒執(zhí)行shell命令,這時候突然想到個現(xiàn)象。
一般遇到這種情況的時候,都是同一時間執(zhí)行的那些服都在一臺服務(wù)器上的時候,會不會是ssh那邊的問題導(dǎo)致同一時間連過去的連接過多,拒絕了一些導(dǎo)致有些服沒執(zhí)行成功呢?那么既然這么懷疑,就讓我們驗(yàn)證下吧。
在同一目標(biāo)機(jī)上的24個服執(zhí)行,看下目標(biāo)機(jī)的ssh log:

果然,在/var/log/secure只過濾到21個ssh連接,還有3個丟失了,與執(zhí)行機(jī)上顯示失敗的數(shù)量一致,找到問題了!
那么看看sshd_config里如何定義的:
#MaxAuthTries 6
#MaxSessions 10
#MaxStartups 10:30:100
與此相關(guān)的參數(shù)有上面三個:
-
#MaxAuthTries 6指的是嘗試連接時輸錯密碼最大的嘗試次數(shù),應(yīng)該與這個無關(guān),我都是用
sshkey連的。 -
#MaxSessions 10指的是每個連接可以并行開啟多少個會話
session,默認(rèn)值是10. -
#MaxStartups 10:30:100指的是限制處于連接頁面時的連接數(shù),默認(rèn)值
10。連接頁面就是當(dāng)你登錄ssh時,還沒輸入密碼的頁面。那么這個
10:30:100是什么意思呢?原來指的是當(dāng)連接數(shù)達(dá)到10時,之后的連接有30的概率被拒絕掉,超過100個連接時就全部決絕掉
那么我們調(diào)整一下:
MaxSessions 100
MaxStartups 100
都調(diào)成100,然后重啟下sshd試試
果然,都成功了?。?!