-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
修复某些情况下测速数值过大的问题 #290
修复某些情况下测速数值过大的问题 #290
Conversation
你这比我分析的都明白。。。 这个问题几年前就有人提过,这几年也陆续有几个人反馈过,但单靠文字交流很难排查问题,最后都不了了之了。 按照你的分析,该 BUG 主要会在以下情况时出现:
我在 Issues 里找了找类似的反馈,发现它们都有个共同点,那就是这些人与 Cloudflare CDN 节点之间的网络质量都很好,随便测速一下都能轻松找到一堆最少几十 MB/s 的 IP,而正因为下载速度太快,下载测速地址的文件又偏小,导致更容易出现还没到 10 秒就把文件完全下载完了的情况,也就更容易触发该 BUG 了。 另外,其中有两个人提到了大量测速时遇到该 BUG,然后把这些异常的 IP 单独拿出来测速又正常了,似乎该问题在大量下载测速时更容易出现,而单独测速几个 IP 的话,又似乎难以复现。 不过我刚才专门找了两个小文件,来回进行下载测速,发现一次都没遇到,是我复现步骤不对?还是运气不好。。。
|
另外,刚才翻 Issues 时还找到了这个 #200 我用目前 v2.2.0 版本与你修复后的 CloudflareST 的进行了对比,发现 v2.2.0 版本:
而你修复后的 CloudflareST 则不存在该问题,即使是 200 MB 10 秒 也能正确输出下载速度结果。 但奇怪的是,v2.2.0 版本用另一个下载测速地址却正常,不知道是不是 CF 官方下载测速地址的问题:
不过仔细对比后发现,同样是小文件,两个 CloudflareST 结果还是存在差异,修复后的下载测速结果往往都比 v2.2.0 版本的低一些(几MB/s ~ 几百MB/s 不等,即使放大到 300 MB 的文件也依然如此)。 另外,根据反馈信息来看,似乎在 Linux 系统下该 BUG 更容易复现(即他们在路由器上经常遇到该问题,但在 Windows 系统下测速却没有遇到,不过我没有海外 Windows 服务器所以也无法验证这点。。。 既然复现成功并可以观察到结果修正了,那就合并吧,稍后我会发布新版本,也会通知上面那些 Issues 反馈的人去更新尝试~ |
感谢charSLee013,我更新新版本cfst后,貌似不能复现超速的问题了~ |
有人反馈出现下载速度 0.00 的情况,我排查后发现问题出在你提到的 "其他 BUG" 上。 if err != io.EOF { // 文件下载完了,或因网络等问题导致链接中断,则退出循环(终止测速)
break
} 我仔细分析了下该代码的作用,发现其并不是写错了,而是本来就应该这样(!=),不过我的注释是明显写错了。。。 最终我分析出来该代码的正确注释应该是这样: if err != io.EOF { // 如果文件下载过程中遇到报错(如 Timeout),且并不是因为文件下载完了,则退出循环(终止测速)
break
} 并非是我以前注释所写的什么 “文件下载完了balabal...”,如果是文件下载完了,那么该循环 如果是其他报错,那么就直接跳出循环即可。 总之,这算是一个因为 注释不规范+测试不完全 导致的 BUG 。。。 |
感谢 XIU2 修正,我也忽略了超时或者其他错误的情况下应该退出的循环的 |
先说下
CloudflareSpeedTest
的测速方法创建一个 移动加权平均数
e
根据
Timeout
切分成多个均匀的时间点,比如默认的时间点的间隔是 100ms那么时间点分布就像是
0 .. 100 .. 200 .. 300 .. 400 .. 500
在超过时间点后,将此时间片内的增量数据添加到
e
内有种特殊情况是当下载已经完成,还没到达下一个时间点的时候
会将 增量数量 / ((下个时间点 - 当前时间) / 时间片)
问题出在 下个时间点 - 当前时间,如果当前时间是 492ms, 而下一个时间点是 500ms,那么得出时间差是 8ms ,相当于计算的是 8ms 内增量数据
正确的算法应该是 当前时间 - 上个时间点 得出是 492 - 400 = 92ms ,计算的是92ms 内的增量数据
所以在距离下个时间点非常接近的时候,就会导致测试的数字膨胀过大
其他bug
还有段这样的代码
按照原本的意思应该是当遇到
io.EOF
就退出才对,这也顺便改正过来了