记一次对MC取数据时间不敏感Debug过程

故障描述:客户端线上页面偶现白页

Debug 过程流
0、第一反应是部分服务器挂了,很快排除。
1、CURL请求页面数据API,一直有数据。跟端上沟通,端上会有超时出现白页的情况。查接口果然超时。
2、如何处理?第一反应是如何做性能优化,而不是为什么会超时。当然,性能优化前提也是要分析超时原因,即性能瓶颈。【事后来看第一时间问为什么会超时的思维更高效】

3、性能分析优化BEGIN。
为了方便说明,先模拟场景并伪码描述一下主要实现逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// 场景模拟:一个页面中有多个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就应该意识到问题了。
解决问题想当然了,一开始没有打印循环内部单次执行的时间。【多几次循环时间开销真的不是想象的那么大】

发表评论

电子邮件地址不会被公开。 必填项已用*标注