2019独角兽企业重金招聘Python工程师标准>>>
2017-3-14碰到的两个问题。出现问题的机器是一台windows服务器,windows2008R2 standard 64位,Python2.7.9。
其实是两个问题夹杂在一起的,首先碰到的问题是:
No handlers could be found for logger "paramiko.transport"
这个问题和下面的第二个问题是夹杂在一起的。
问题的根源在于,测试代码中使用到了tornado的logger,root logger没有设置handlers,而针对'tornado.application'的logger设置了handlers(StreamHandler),所以需要修改测试代码,设置默认的root的handlers为NullHandler,而设置'tornado.application'的logger为StreamHandler。参考sysmgt项目中的test.py。(本质就是root logger没有设置handlers,导致其他logger因为继承它而也没有handlers,而只有唯一设置了的'tornado.application'这个logger可以正常输出)
第二个问题是在修复第一个问题后依然存在,错误(模拟测试)为:
D:\temp\py>python paramiko_test.py
test paramiko ........
time1 : [0.0] - 10.99.201.174 - wcadmin
time1 : [0.0] - 10.122.2.6 - wcadmin
time2 : [0.0] - 10.99.201.174 - wcadmin
time2 : [0.0] - 10.122.2.6 - wcadmin
time3 : [0.0] - 10.99.201.174 - wcadmin
time3 : [0.0] - 10.122.2.6 - wcadmin
time4 : [0.0] - 10.99.201.174 - wcadmin -
time4 : [0.0] - 10.122.2.6 - wcadmin -
--- ip=10.99.201.174, username=wcadmin, password=
--- ip=10.122.2.6, username=wcadmin, password=
Traceback (most recent call last):
File "paramiko_test.py", line 42, in one_connection
sshclient.connect(ip, 22, username, password)
File "C:\app\Python27\lib\site-packages\paramiko\client.py", line 338, in connect
t.start_client(timeout=timeout)
File "C:\app\Python27\lib\site-packages\paramiko\transport.py", line 500, in start_client
raise e
RequirementParseError: Invalid requirement, parse error at "''"
time5 : [0.452000141144] - 10.99.201.174 - wcadmin
time6 : [0.46799993515] - 10.99.201.174 - wcadmin
上面是测试程序(多线程连接远程服务器)的测试结果。同样的程序在我自己电脑没有问题。
RequirementParseError: Invalid requirement 这个问题不是每次运行测试程序都会出错,出错的概率感觉在85%。
解决过程:
1 怀疑过时pip版本的问题,最后卸载后又安装。因为没找到老版本的pip,所以pip前后都是新版本。后来证明了这跟pip无关。
2 怀疑paramiko的版本问题,将paramiko由1.*升级到2+。依然有问题。
3 根据网上类似问题,是说是setuptools库的问题,卸载,然后安装,报找不到模块appdirs。下载并安装模块appdirs。然后安装新版本的setuptools,即解决该问题。
老的setuptools的版本为22.0.0,而新安装的是34.3.2.。我本机的版本为16.0。所以看来是setuptools某个版本与paramiko冲突。将服务器上的setuptools版本降级,问题解决。
3.15日,发现服务器上setuptools虽然降级当时测试没问题,实际是没有深入测试,线程并发多了后还是有同样的问题。
于是将我本机的setuptools卸载后安装最新版本,复现了服务器上的问题。在Linux机器上测试,setuptools在高版本时也有问题。接下来找到一篇文章,说将setuptools的版本降到20.2一下。所以最后采用19.7这个版本,经过测试没有问题。
不知道问题会不会复现,再看吧。
3.15日,在服务器端反复安装卸载setuptools和pip,发现一些情况,不是特别明白。
1 pkg_resources这个模块,查阅资料,应该是加载模块用的,在python安装后它出现在$python_home/Lib/site-packages下,当时有时安装最新的pip和setuptools后发现在site-packages下的pkg_resources不在了,而出现在setuptools中。
2 在多次安装卸载pip setuptools后发现pip.exe和pip-script.py不见了,导致pip不能用,因为操作多次,不知道是哪次出现这个问题,只好把其他机器上这两个文件拿来用。不知道其他文件是否也丢失。
针对第二个问题,在网上找到一个办法,执行下面命令:
python -m pip install --upgrade pip --force-reinstall
本文发表于开源中国OSCHINA,当时以为已经解决了问题,结果第二天问题依然存在,结果就在网上继续搜索,发现本文已经被某网站转载,我估计是通过网页爬虫抓取自动发表,所以今日更新,过几天看看是否还会被爬取:)。
我的测试程序:
#-*-coding:UTF-8-*-
__author__='zhaoxp'
import traceback
import logging
import time
import threading
import paramiko
logging.basicConfig(level=logging.DEBUG)
logging.getLogger().handlers=[logging.NullHandler()]
logger = logging.getLogger('paramiko.test')
logger.handlers.append(logging.StreamHandler())
logger.setLevel(logging.DEBUG)
def main():
threads = []
threads.append(threading.Thread(target=one_connection, args=('10.99.201.174', 'wcadmin', 'password')))
threads.append(threading.Thread(target=one_connection, args=('10.122.2.6', 'wcadmin', 'password')))
threads.append(threading.Thread(target=one_connection, args=('10.99.201.37', 'wcadmin', 'password')))
threads.append(threading.Thread(target=one_connection, args=('10.99.244.121', 'wcadmin', 'password')))
for th in threads:
th.start()
for th in threads:
th.join()
def one_connection(ip, username, password):
sshclient = None
try:
start_time = time.time()
logger.debug('time1 : [%s] - %s - %s'%(time.time()-start_time, ip, username))
sshclient=paramiko.SSHClient()
logger.debug('time2 : [%s] - %s - %s'%(time.time()-start_time, ip, username))
sshclient.load_system_host_keys()
logger.debug('time3 : [%s] - %s - %s'%(time.time()-start_time, ip, username))
sshclient.set_missing_host_key_policy(paramiko.AutoAddPolicy())
logger.debug('time4 : [%s] - %s - %s - %s'%(time.time()-start_time, ip, username, password))
logger.debug('--- ip=%s, username=%s, password=%s'%(ip, username, password))
sshclient.connect(ip, 22, username, password)
logger.debug('time5 : [%s] - %s - %s'%(time.time()-start_time, ip, username))
stdin, stdout, stderr = sshclient.exec_command('pwd')
#logger.debug('stdout:\n%s \n stderr:\n%s \n'%(stdout.read(), stderr.read()))
logger.debug('time6 : [%s] - %s - %s'%(time.time()-start_time, ip, username))
except BaseException as be:
traceback.print_exc()
finally:
if sshclient is not None:
sshclient.close()
if __name__=='__main__':
print 'test paramiko ........'
main()