記一次ssh配置導(dǎo)致的python多線程腳本失敗的排查過程

pythonthreading模塊寫了個部署腳本,使用中總遇到個奇怪問題。

先看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只過濾到21ssh連接,還有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試試

果然,都成功了?。?!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容