apt更新时会触发/usr/lib/cloud-init/ds-identify的运行。然后这个脚本运行的非常的慢。要 1 分多钟才会运行完。期间 CPU 是满的。而且新的 ssh 连接无法建立。
这个 ds-identify 是个 shell 脚本。ds-identify开头是#!/bin/sh,用的是系统默认的dash。
我自己按照 top 中显示的命令行信息,增加-x参数,运行/bin/sh -x /usr/lib/cloud-init/ds-identify,也非常慢,但能看到,卡在check_config函数的while read line之后,line=之前。
for fname in "$@"; do
[ -f "$fname" ] || continue
while read line; do
line=${line%%#*}
case "$line" in
$key:\ *|$key:)
ret=${line#*:};
ret=${ret# };
found=$((found+1))
found_fn="$fname";;
esac
done <"$fname"
done
这“应该”是在读文件内容。
根据打印信息,读取的是/etc/cloud/cloud.cfg.d/aliyun_cloud.cfg文件,并且是- echo 开头的很长的一行文本上。
多次执行,发现只要是在文件中的行内容过长的地方,就会 read 的很慢。
然后我用bash执行了一遍。发现同样的ds-identify,却执行的非常快。
初看像是dash的某种性能问题。
我新建一个文本文件test.cfg,将/etc/cloud/cloud.cfg.d/aliyun_cloud.cfg文件的内容复制进去。
新建一个独立的test.sh脚本文件,将上面那段函数放进去。
执行这个test.sh脚本来读取test.cfg文件。
发现用dash和bash都执行的非常快。所以不是dash的某种性能问题!
aliyun_cloud.cfg的问题通过ls,我观察到/etc/cloud/cloud.cfg.d/aliyun_cloud.cfg文件其实是个链接。
aliyun_cloud.cfg -> /sys/firmware/qemu_fw_cfg/by_name/etc/cloud-init/vendor-data/raw
我直接cat这个链接文件的内容,显示的很快。不像是某种 IO 问题。
我修改上面的test.sh脚本,直接读取aliyun_cloud.cfg这个链接文件。
然后,用bash这个 shell 读取的非常快,但用dash这个 shell 读取的却非常慢!
因为/usr/lib/cloud-init/ds-identify这个脚本是系统在某个时刻调用的。我现在的绕过方式只能是将/bin/sh的默认指向改为bash。
我不确定为什么dash读取阿里云的这个文件很慢,而bash却很快。
希望有大佬能提供点调试思路。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.