用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 重启完毕! 结束时间: %s ##########\033[0m\n" %(server, dir_name, time.strftime('%H:%M:%S',time.localtime(time.time())))
semaphore.release()
再看如何调用的:
elif cmd == 'thread_cmd':
#run_cmd = sys.argv[3]
thread_num = 80
check = raw_input("\033[1;31;40m确认要 并行 重启 %s 吗? 此次启动线程数为 %d 个!\033[0m\n" %(zone, thread_num))
semaphore = threading.BoundedSemaphore(thread_num)
if check == 'yes':
print "\033[1;31;40m########## 重启 %s 任务开始 启动线程数为 %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退出 请重新确认!\033[0m"
基本流程就是启80个线程,每个线程去特定的ip,特定的目录去执行shell脚本
但是有时会遇到下图中的情况,红框中的那些没有执行直接就返回print
的结果了
之后咨询了公司里的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 重启完毕! 结束时间: %s ##########\033[0m\n" %(server, dir_name, time.strftime('%H:%M:%S',time.localtime(time.time())))
semaphore.release()
再执行结果如下:
红框中的几个服确实是没执行shell
命令,这时候突然想到个现象。
一般遇到这种情况的时候,都是同一时间执行的那些服都在一台服务器上的时候,会不会是ssh
那边的问题导致同一时间连过去的连接过多,拒绝了一些导致有些服没执行成功呢?那么既然这么怀疑,就让我们验证下吧。
在同一目标机上的24
个服执行,看下目标机的ssh log
:
果然,在/var/log/secure
只过滤到21
个ssh
连接,还有3
个丢失了,与执行机上显示失败的数量一致,找到问题了!
那么看看sshd_config
里如何定义的:
#MaxAuthTries 6
#MaxSessions 10
#MaxStartups 10:30:100
与此相关的参数有上面三个:
-
#MaxAuthTries 6
指的是尝试连接时输错密码最大的尝试次数,应该与这个无关,我都是用
sshkey
连的。 -
#MaxSessions 10
指的是每个连接可以并行开启多少个会话
session
,默认值是10
. -
#MaxStartups 10:30:100
指的是限制处于连接页面时的连接数,默认值
10
。连接页面就是当你登录ssh
时,还没输入密码的页面。那么这个
10:30:100
是什么意思呢?原来指的是当连接数达到10时,之后的连接有30的概率被拒绝掉,超过100个连接时就全部决绝掉
那么我们调整一下:
MaxSessions 100
MaxStartups 100
都调成100
,然后重启下sshd
试试
果然,都成功了!!!