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.pytest paramiko ........time1 : [0.0] - 10.99.201.174 - wcadmintime1 : [0.0] - 10.122.2.6 - wcadmintime2 : [0.0] - 10.99.201.174 - wcadmintime2 : [0.0] - 10.122.2.6 - wcadmintime3 : [0.0] - 10.99.201.174 - wcadmintime3 : [0.0] - 10.122.2.6 - wcadmintime4 : [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 eRequirementParseError: Invalid requirement, parse error at "''"time5 : [0.452000141144] - 10.99.201.174 - wcadmintime6 : [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 tracebackimport loggingimport timeimport threadingimport paramikologging.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()