乐趣区

线上模块XX 在高QPS下耗时剧增的原因排查总结

1、确定问题原因:1)场景复现:方式 1:根据现场日志确定问题原因;方式 2:压测复现。存在的问题:方式 1:日志中没有保存现场;方式 2:压测可能与线上不符;压测可能无法满足某些特殊条件。2)一些手段:a. 如果问题只在特定机器出现,确定机器硬件配置是否相同,cpu、meminfo、系统配置等;b. 分阶段、逐步细化各步骤的处理时间、队列积压长度等;c. 可以使用一些辅助性能分析工具进行分析,代价是学习成本,场景不一定符合性能分析工具作用的发挥。最终发现的高 qps 时,耗时主要集中在信息流配图阶段和 it_proc 特征收集阶段。

2、分析现象本质:1)it_proc: 内部循环过多:按照 it 内部的参数默认值计算,最大循环次数达到百万级别,在其他特征收集基本 0ms 的情况下,it 的耗时是不可接受的。2)信息流配图:分阶段、逐步细化各步骤的处理时间并不能发现问题原因,这种情况就不能怀疑单次执行内部函数的耗时上,很有可能是系统在做切换、同步等处理时导致的异常。对这一部分程序重新研读,发现调用的 std 标准函数 random_shuffle 有重大嫌疑,在此怀疑的基础上,注释掉相关代码,确实不再发生同样的问题,问题得到确认。
问题参考资料:http://www.cplusplus.com/refe…is-random-shuffle-threadsafe-and-using-rand-r-if-it-is-nothttps://github.com/mariusmuja…
3、问题修复方式:1)it_proc: 和策略同学讨论修复方式,谁开发谁维护的原则,发现是按权重抽样算法过于复杂,最后确定已现有 ot 的处理方式进行修改;2)信息流配图:a. 信息流配图也存在大量循环,首先将不需要再循环内部执行的代码移到循环体外部,其次尽量在不影响功能的情况下降低循环次数。b. 对于 random_shuffle 的问题,采用基于 rand_r 自定义随机生成器的方式调用 template void random_shuffle (RandomAccessIterator first, RandomAccessIterator last,RandomNumberGenerator&& gen); 实现数组打散。
4、总结:1)性能问题排查的思路和步骤(定位问题比解决问题更加困难,无法定位问题就更谈不上解决问题)2)代码优化的原则:a. 阿姆达尔定律:不经常使用的代码不需要做较多优化考虑,即让经常执行的路径运行更加高效,而运行稀少的路径正确执行。b. 先保证代码的正确性,再考虑优化。c. 优化所需的时间常常是写代码时间的 double。3)优化分为系统级别的优化和代码级别的优化系统级别的优化常常需要模块或子模块的重构,需要从顶端开始出方案和设计。推荐书目:《重构 - 改善既有代码的设计》代码级别的优化更多的是使用一下小技巧实现,如果可以参考这几个链接:
http://www.jb51.net/article/5…http://blog.csdn.net/wind19/a…

退出移动版