背景
用Linux的同学应该都知道yum,是用来管理系统软件包的,非常快捷,可以自动解决包依赖问题。
但真正了解yum的工作原理的人估计并不多。
本文记录一次在公司云平台上遇到无法使用yum的问题。
问题重现
在虚拟机上安装包(比如tcpdump),报Timeout
28, 'Operation too slow. Less than 1 bytes/sec transfered the last 30 seconds'
乍一看,感觉是和repo服务器连接太慢,所以Timeout了,实际情况是不是这样呢?我们用strace命令来分析下过程。
原因分析
可以把strace结果保存到文件中,打开慢慢看,也可以指定只输出特定system call。
strace -s 2000 -f -o yum.output yum install tcpdump
strace -s 2000 -f -e poll,select,connect,recvfrom,sendto yum install tcpdump
"-s 2000":规定输出最大字节为2000,默认是32,太小了,会导致我们忽略一些重要信息。
"-f":追踪所有子进程
这里我概述下结果:
strace先查找nscd有没有cache对应的dns记录,然后查找/etc/resolv.conf里面的dns服务器的地址,然后判断出repo主机的IP地址。
之后系统给repo主机发出sendto() GET请求,请求获取repos.xml文件,但最后都一直显示poll() Timeout 。
由此我们知道原因是根本连不上repo服务器。
那是不是真的连不上repo服务器呢?
我用wget/curl 尝试了下,发现可以下载repos.xml文件。说明repo服务器的80口是通的。
哎,这就奇怪了,为什么用不用的工具返回的结果却不一样呢?
想来想去,只有Header不一样。
我们回过头重新看下strace的结果,发现yum用的User-agent是“urlgrabber/3.1.0 yum/3.2.22”,而wget用的是Wget/1.12 (linux-gnu) , 所以我们需要修改对应的yum源码文件。
vim /usr/lib/python2.6/site-packages/yum/yumRepo.py
先备份下,然后做如下修改,把第一行改为第二行:
'user_agent': default_grabber.opts.user_agent,
'user_agent': 'Wget/1.12 (linux-gnu)',
保存好后,清除所有yum缓存
yum clean all
再安装tcpdump包
yum install tcpdump
刷的一下,弹出来熟悉的东西,成功了!!
问题思考
到此问题算是解决了,但后面还有工作要做,就是repo服务端为什么对请求的Header做了限制?它是怎么做限制的?
本文介绍了一次在云平台上遇到的使用yum安装软件包时出现超时问题,并通过strace命令进行问题定位,最终发现是由于User-agent不同导致的repo服务器响应差异,通过修改User-agent解决了问题。
1万+

被折叠的 条评论
为什么被折叠?



