故障描述:客户端线上页面偶现白页
Debug 过程流
0、第一反应是部分服务器挂了,很快排除。
1、CURL请求页面数据API,一直有数据。跟端上沟通,端上会有超时出现白页的情况。查接口果然超时。
2、如何处理?第一反应是如何做性能优化,而不是为什么会超时。当然,性能优化前提也是要分析超时原因,即性能瓶颈。【事后来看第一时间问为什么会超时的思维更高效】
3、性能分析优化BEGIN。
为了方便说明,先模拟场景并伪码描述一下主要实现逻辑
// 场景模拟:一个页面中有多个Tab, 每个Tab中有多个模块,每个模块中有多个商品信息。需要把页面中全部商品按价格降序排列。 // 功能描述:获取全部商品并排序 class Test { // 在controller中 public static function index() { $tab_ids = [1000, 2000, 3000, 4000, 5000]; $mod_ids = []; foreach ($tab_ids as $tab_id) { // 调用获取一个tab下全部模块全部商品方法getSkus(); $res[] = $this->getSkus(); } // sort sortFunction(); return []; } // 在model中 public static function getSkus($tab_id) { // 获取到tab下全部模块$mod_ids foreach ($mod_ids as $mod_id) { // 取模块信息方法getData(); 调用一次 getData(); 又调用一次 getData(); do something; } return 数据; } // 在data【library】中 public static function getData($id) { 获取MC中数据 if (MC数据有效) { return MC数据; } 取DB数据 if (条件)) { set DB数据到MC; } return DB数据; } }
3.1、分片打印代码执行时间,很快发现line 10 执行时间很长。然后分析发现getSkus()中调用了两次getData()。
3.2、想了个办法把两次getData()调用合并了。打印执行时间并没有快多少。
3.3、打印line 12中方法执行时间发现差不多都是200ms, 但是到第4次循环就突变成1s多了。
3.4、故障比较紧急,就临时处理了,在index中加了一层1分钟缓存。
3.5、问题暂时解决。性能分析优化END。
4、后来发现line 44从DB取数据后,没有满足写MC的条件,MC缓存是1天,于是知道问题症结是缓存每次都被穿透了。
5、总结:
对MC取数据时间不敏感。单次取MC达到200ms就应该意识到问题了。
解决问题想当然了,一开始没有打印循环内部单次执行的时间。【多几次循环时间开销真的不是想象的那么大】