• 记录一个protobuf枚举类型引发问题的分析和思考


    背景:

      项目使用protobuf作为socket传输数据的序列化协议 数据对象的定义时 使用了很多枚举类型

    人物:

      这部分代码经手应该超过3位以上程序员

    起因:

      为了丰富聊天内容形态 增加了新的消息类型(嫌原单图展示死板 增加了多图合并展示的消息类型)

    经过:

      正常的开发、提测, dang!!发现老版本在进入聊天界面时会必先崩溃 排查发现原因

      protobuf 对象生成的java对应的代码中 旧版本不认识新版本数据 导致枚举类型的值为 UNRECOGNIZED(-1)

      旧代码中通过getNumber()获取对应值的时候直接抛出异常(方法定义中并没有声明) IllegalArgumentException("Can't get the number of an unknown enum value.");

    结果:

      很明显 旧版本不能兼容新加的类型

    解决:

      其实很多方法可以解决这个问题

      其中比较理想的是

        如果项目之前引入热修复的话 这里打个补丁 改一下代码(可惜没如果)

        服务器端增加客户端版本判定 将新类型转成旧类型处理 不过 如果处理不当可能造成丢图(没办法对我们来说这是最好的结果了)

      还有相对不理想的

        比如先给旧版本来一个小升级 解决这个问题(要等用户大量升级小版本之后才能上最新版本 周期比较长)

        旧版本强制升级(会造成一定量的用户流失)

    思考:

      其实这个问题很好排查也很好解决 但是却能留给我一些思考 

      1 如果protobuf生成的代码 能将抛出的异常写在方法声明里 其实就可以提醒调用者注意这个部分的问题

      2 如果当初写这个对象转换逻辑的人 在获取枚举对应值的时候发现生成代码的问题 使用get*Value()而不是get*().getNumber()

      3 早点引入热修复也是 

      4 如果项目组定期组织代码review 也许也能发现问题

    记:

    即便是大公司 较成熟的协议 使用起来也可能存在隐患

    掉过越多坑的程序员 越有价值

    早为未来做打算

    闲暇时间多翻翻之前的(无论是谁写的)代码 即便是互相挑刺 对项目来讲 是好事情

  • 相关阅读:
    kafka集群partition分布原理分析
    Kafka的通讯协议
    RabbitMQ和Kafka
    深入理解kafka设计原理
    Kafka的Log存储解析
    Netty 超时机制及心跳程序实现
    Netty 实现 WebSocket 聊天功能
    Netty 实现聊天功能
    RabbitMQ在分布式系统中的应用
    Kafka文件存储机制那些事
  • 原文地址:https://www.cnblogs.com/waterbear/p/10740630.html
Copyright © 2020-2023  润新知