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
- 全域性名稱空間
- Laravel 關聯模型由於名稱一致性導致的問題Laravel模型
- 建立一個日期 + 字元的使用者名稱字元
- 一個關於資料庫關閉很有意思的現象資料庫
- IIS 無法識別的屬性“targetFramework”。請注意屬性名稱區分大小寫。Framework
- Python的一個名稱空間衝突,關於from-import機制PythonImport
- oracle中的某一個使用者名稱修改Oracle
- 有意思!一個關於 Spring 歷史的線上小遊戲Spring遊戲
- 新時代佈局中一些有意思的特性
- 分享一個有意思的錯誤
- MySQL一個有意思的問題MySql
- 一個無名前端的10年前端路前端
- Android Q:新系統名稱和新特性整理Android
- 二、修改資料庫全域性名稱資料庫
- 與軟體相關的職業名稱
- C#解決一個奇怪的,名稱空間“XXX”中不存在型別或名稱空間名稱“xxx”的問題C#型別
- Outlook使用anywhere提示安全證書上的名稱無效或與網站的名稱不相符網站
- TNS-03505 名稱無法解析
- 個性簽名
- 一個轉換資料屬性名的工具
- 一個頗有意思的SQL語句SQL
- Thrift使用入門(2) - 用Thrift實現一個簡單的Server/Client應用程式Serverclient
- 2.6.2 確定全域性資料庫名稱資料庫
- PowerShell快速修改多個檔案的名稱
- 【oracle】TNS-03505: 無法解析名稱Oracle
- 開發一個屬性名提示友好的Vue元件Vue元件
- React Suite 做了一個有意思的決定ReactUI
- 一個有意思的CSS圖片hover效果CSS
- 事務的特性:事務必須具備以下四個屬性,簡稱ACID
- hadoop之 hadoop 2.2.X 棄用的配置屬性名稱及其替換名稱對照表Hadoop
- 一、更改ORACLE SID名稱Oracle
- 透過Lambda函式的方式獲取屬性名稱函式
- Sql Server使用者名稱和登入名的關係總結SQLServer
- 簡短好聽英文個性簽名大全 一句話英文個性簽名帶翻譯
- 關於RAC共享儲存兩個節點磁碟裝置名稱不一致的問題
- 對名稱空間的一點個人理解