一次关于 smokeping TCPPing 效率过低的检查
最近给家里的古代实例 smokeping 一次加了 几十 个 TCPPing target 来全面探测出国网络质量,但是发现没有数据生成。
探索日志易得大量:
```bash
TCPPing: <censored>: timeout (11 s) reached, killing the probe.
```
可以猜到,问题出自配置的 `timeout = 1` + `pings = 10`。
自行运行 TCPPing 对应的脚本可知,其每次 ping 所需时间约为 15 秒。
但是对于一个延迟不过 100ms 的目标而言为何需要比默认已经非常过分的 10 秒更高的超时时间呢?
## 无脑处理
在对 smokeping 用的 tcpping 进行 `bash -x` 后不难发现,卡是卡在了对 `tcptraceroute` 的调用,这是一个古代程序,因为现代 `traceroute` 已经支持 TCP 了。
对于古代物品的第一维修方式,自然应当是考虑进行更新。
于是我在 [这里](https://github.com/deajan/tcpping/blob/master/tcpping) 找到了支持新版 `traceroute` 的兼容 smokeping 参数的脚本并进行替换。
每次 ping 所需时间成功降低到 5s,看起来似乎不错,但是对于较大规模的 target 来说仍然难以忍受。
对于恰好卡在线上的规模,可能会见到:
```
TCPPing: WARNING: smokeping took 120.916475057602 seconds to complete 1 round of polling. It should complete polling in 120 seconds. You may have unresponsive devices in your setup.
```
通过增加并发数可以缓解,但那也太不优雅了。
## 探索
正如前文所说,卡的根源对 `tcptraceroute` / `traceroute` 的调用,对这两个程序手动调用时,我的随手测试用例 `223.5.5.5` `192.168.0.1` 是非常快的,而自己 VPS 的测试则非常缓慢。
而比较其输出,可以发现,较快的测试用例或是保留地址、或是有 rDNS,但较慢的地址并没有。
`traceroute` 支持使用 `-n` 来取消 rDNS,通过指定这一参数后,原本较慢的调用也变得极为顺滑。
原来是 rDNS 卡了,也非常合理。
## 实践
直接把原装脚本简单粗暴 patch 一下来用:
```bash
--- "a/tcpping.sh"
+++ "b/tcpping-mod.sh"
@@ -50,7 +50,7 @@ usage () {
}
_checksite() {
- ttr=`tcptraceroute -f ${ttl} -m ${ttl} -q ${q} -w ${w} $* 2>&1`
+ ttr=`tcptraceroute -n -f ${ttl} -m ${ttl} -q ${q} -w ${w} $* 2>&1`
if echo "${ttr}" | egrep -i "(bad destination|got roo)" >/dev/null 2>&1; then
echo "${ttr}"
exit
@@ -62,7 +62,7 @@ _testsite() {
shift
[ "${c}" = "yes" ] && nows=`date +${format}`
[ "${d}" = "yes" ] && nowd=`date`
- ttr=`tcptraceroute -f ${ttl} -m ${ttl} -q ${q} -w ${w} $* 2>/dev/null`
+ ttr=`tcptraceroute -n -f ${ttl} -m ${ttl} -q ${q} -w ${w} $* 2>/dev/null`
host=`echo "${ttr}" | awk '{print $2 " " $3}'`
rtt=`echo "${ttr}" | sed 's/.*] //' | awk '{print $1}'`
not=`echo "${rtt}" | tr -d ".0123456789"`
```
结果运行良好,非常顺滑。
评论
发表评论