記錄一個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 也許也能發現問題

記:

即便是大公司 較成熟的協議 使用起來也可能存在隱患

掉過越多坑的程序員 越有價值

早為未來做打算

閑暇時間多翻翻之前的(無論是誰寫的)代碼 即便是互相挑刺 對項目來講 是好事情


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM