thrift 一個有意思的特性:Class名稱無關性
最近開發的一個專案,後端採用thrift框架來提供rpc服務(java語言實現),然後前端採用php語言來生成thrift client呼叫後臺RPC服務。由於某些原因,上週我把thrift定義檔案中一個struct名稱修改了,當然也沒多想,順手就把java服務端重新編譯部署,而php前端的部署未做任何變化,按常規理解,服務契約中的類名,從A改成B,服務的呼叫方理應同步更新部署,否則感覺應該會出錯。
然而,美好的事情就這麼發生了,一切執行正常,依舊絲絲順滑!
再然後,我就開始思考人生,重新理解 thrift內部的序列化與反序列化機制,很快就想明白了,借用之前寫過的部落格rpc框架之 avro 學習 2 - 高效的序列化中的一張圖:
thrift內部儲存二進位制資料時,為了提高儲存效率,每個field都分配了一個數字編號,所以在序列化及反序列化時,其實是隻認數字編號,不管名稱的,這也正是thrift IDL檔案定義struct時,為什麼強制要求每個成員都要指定一個在struct本身範圍內不重複的數字序號
struct PersonModel { 1: i16 age = 0, 2: string name, 3: bool sex, 4: double salary, 5: byte childrenCount}
IDL生成的具體語言的原始碼中,解析物件時,同樣也只看序號,以c#生成的程式碼為例:
1 public void Read (TProtocol iprot) 2 { 3 iprot.IncrementRecursionDepth(); 4 try 5 { 6 TField field; 7 iprot.ReadStructBegin(); 8 while (true) 9 { 10 field = iprot.ReadFieldBegin(); 11 if (field.Type == TType.Stop) { 12 break; 13 } 14 switch (field.ID) 15 { 16 case 1: 17 if (field.Type == TType.I16) { 18 Age = iprot.ReadI16(); 19 } else { 20 TProtocolUtil.Skip(iprot, field.Type); 21 } 22 break; 23 case 2: 24 if (field.Type == TType.String) { 25 Name = iprot.ReadString(); 26 } else { 27 TProtocolUtil.Skip(iprot, field.Type); 28 } 29 break; 30 case 3: 31 if (field.Type == TType.Bool) { 32 Sex = iprot.ReadBool(); 33 } else { 34 TProtocolUtil.Skip(iprot, field.Type); 35 } 36 break; 37 case 4: 38 if (field.Type == TType.Double) { 39 Salary = iprot.ReadDouble(); 40 } else { 41 TProtocolUtil.Skip(iprot, field.Type); 42 } 43 break; 44 case 5: 45 if (field.Type == TType.Byte) { 46 ChildrenCount = iprot.ReadByte(); 47 } else { 48 TProtocolUtil.Skip(iprot, field.Type); 49 } 50 break; 51 default: 52 TProtocolUtil.Skip(iprot, field.Type); 53 break; 54 } 55 iprot.ReadFieldEnd(); 56 } 57 iprot.ReadStructEnd(); 58 } 59 finally 60 { 61 iprot.DecrementRecursionDepth(); 62 } 63 }
從上面的case語句可以很清楚的看出,程式碼內部只認數字序號,不關心名稱。
結論:只要不改變struct內部的成員型別和數字編號,struct對應的類名可以放心大膽的修改。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2144/viewspace-2801334/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- PbootCMS提示:URL名稱與模型URL名稱衝突,請換一個名稱!boot模型
- PHP 核心特性 - 名稱空間PHP
- 一個有意思且有用的手法——關閉ping
- 對名稱空間的一點個人理解
- 建立一個日期 + 字元的使用者名稱字元
- oracle中的某一個使用者名稱修改Oracle
- Android Q:新系統名稱和新特性整理Android
- 分享一個有意思的錯誤
- 新時代佈局中一些有意思的特性
- 有意思!一個關於 Spring 歷史的線上小遊戲Spring遊戲
- 從外部獲取一個django專案的所有model名稱Django
- 一個轉換資料屬性名的工具
- 一個無名前端的10年前端路前端
- 一個有意思的數學東西
- PowerShell快速修改多個檔案的名稱
- 2.6.2 確定全域性資料庫名稱資料庫
- 開發一個屬性名提示友好的Vue元件Vue元件
- 透過Lambda函式的方式獲取屬性名稱函式
- Spring竟然可以建立“重複”名稱的bean?—一次專案中存在多個bean名稱重複問題的排查SpringBean
- 如果一個標籤元素同時出現兩個class屬性,兩個class都會生效嗎?為什麼?
- 同一個POD中預設共享哪些名稱空間
- React Suite 做了一個有意思的決定ReactUI
- 一個有意思的CSS圖片hover效果CSS
- 一個很有意思的選擇表情DialogActivity
- 『無為則無心』Python函式 — 31、名稱空間(namespace)Python函式namespace
- 簡短好聽英文個性簽名大全 一句話英文個性簽名帶翻譯
- git 使用者名稱密碼相關Git密碼
- 關於System.Web.Script.Serialization名稱空間的引用Web
- 一個很有意思的hook庫:react-hangerHookReact
- C# 11 的這個新特性,我願稱之最強!C#
- Java的每個Thread都希望擁有自己的名稱Javathread
- 資料庫 校驗名稱唯一性,用於新增和修改功能資料庫
- WSL終端使用者名稱顏色無高亮
- es6 class進階【一個將class轉原型物件的例子】原型物件
- HTML class 屬性HTML
- 給執行緒池取一個名稱有助於除錯 - bozho執行緒除錯
- CRUD只是Excel另一個名稱而已,誰想用Excel建立公司的核心繫統?Excel
- class屬性的新增刪除