美文网首页
记一次线上'事故'处理

记一次线上'事故'处理

作者: xiaoyouPrince | 来源:发表于2019-12-23 20:22 被阅读0次

    记一次线上'事故'处理

    今早十点左右(2019年12月23日 10:00), 项目运营反馈新版 App 有闪退问题,我放下手中开发工作,开始排查问题所在:经过查看崩溃日志发现,已经开始大面积影响线上用户了

    15770939012210.jpg

    通过报错信息,我很快确定了问题所在: 新版 App 和旧版本之间本地缓存的兼容问题,由于新版本缓存数据中缓存的键值对新增,导致对新 key 存取值报错。

    具体原因

    项目中网约车模块由之前的「首汽约车」和「红旗智行」两个独立的子项目合并成独立的一个项目。由于平台的融合,项目中管理约车平台和用户类型的类有较大改动。由之前的单平台逻辑修改为现在多平台逻辑。新逻辑如下:

    WX20191223-183759@2x.png

    新版本逻辑中将平台信息和用户类型信息同时保存到了一个字典中,属于字典套字典类型,工具类统一管理顶层字典。可以实现的功能为:用户在 App 中平台信息随时切换,用户类型信息随时切换。约车过程中平台信息也会随着约车状态变化。

    突然想到,这里和 Runloop 中的 Mode 设置的逻辑很像,每个平台下的各个用户类型互不影响。对应不同 Mode 下的源互不影响

    原因

    新版本中只判断了 App 中是否有缓存,遗漏了缓存中没有「sqhq」平台的情况的适配。
    只是判断了有没有缓存文件,有缓存但是没有「sqhq」平台的情况没有处理导致后面崩溃。
    

    影响

    1. 网约车整个模块
    2. 用户退出 App.退出 App 会整体对平台置为最基本的「sqhq」类型
    

    处理方案

    对于用户:   
            卸载 App 重装,彻底清理缓存
    
    对于开发:
            重写缓存数据的处理,对于兼容问题引以为戒
    

    下面是一些问题排查时候的记录

    设计原因

    整个工具类,只提供了类方法处理平台和用户类型的存取。所以缓存文件也放到了类的初始化方法 + initialize 中。

    关于 + initialize 和 + load 方法

    load 方法
        在类或者分类添加到 OC runtime 时候调用,可在此方法中设置类相关的行为
        
        类的 load 方法在新类和新分类添加或链接的时候调用,其中的方法实现会根据最后一次的 load 而确定。类初始化顺序如下
            1. 先初始化自己链接的库文件
            2. 初始化自己类
            3. 初始化项目中 C++ 和 __attribute__(constructor) 
            4. 初始化动态链接自己的 frameworks
            
            其中 load 方法的加载顺序为:superClass -> subClass -> category.
            所以在 load 阶段不要调用其他类的方法,此时其他类的 load 可能还没加载。
            
            
    initialize 方法
        即类的初始化方法,仅为类的初始化,执行顺序位于上面第三步。从方法在类的声明周期内只会执行一次,即分类和类本身只会执行一次。如果做类或者分类的独立处理,需要在 load 方法中。
        此方法调用顺序 superClass -> subClass
        如果在子类调用中调用父类 initialize 可以通过 if (self == [ClassName self]) 来保护父类只执行一次
    

    经验教训

    1. 对于向后兼容问题,需要注意,在测试过程中需要引起注意
    2. 随着用户数增多,突然觉得自己的代码变得更有意义了

    相关文章

      网友评论

          本文标题:记一次线上'事故'处理

          本文链接:https://www.haomeiwen.com/subject/fastoctx.html