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对应的类名可以放心大胆的修改。 

时间: 2024-10-10 22:13:11

thrift 一个有意思的特性:Class名称无关性的相关文章

教你给Mac群组信息设置一个高端的群名称

  当你在 Mac 上的短信应用使用群组对话的时候,你会发现"收件人"一栏写满了群组成员的名字,在某些场合如果显示所有的人名的话,也许并不适合,例如当群组对话信息多起来的话,或许你就分不清哪个群组是负责什么职能了,所以我们可以给群组对话安排一个名字或者一个主题. 如果这是一个工作用的群组,你可以标记为"工作";如果是家人组成的聊天群组,你可以标记为"家庭对话",因而选择一个合适的群组名称有助你区分不同的群组. 1. 首先我们可以打开 Mac 上的

互斥量-一个有意思的关于进程间通信的小问题

问题描述 一个有意思的关于进程间通信的小问题 题目要求: 两个进程Bob与Jack,能够互相看到对方,若对方进程结束,能够唤醒对方进程. 我的思路: 两个进程利用一个公共文件mail.txt,互斥地访问对方的状态,若发现对方不在线,则启动对方进程.mail文件中 1表示进程在线,0表示进程不在线. 现象: 进程间可以相互启动,但总是莫名终止,并且终止后mail文件中的两个进程的状态并不都为0. 我的实现如下:Bob进程 #include #include #include #include us

如何得到一个dataset中某一个表的字段的名称和该数据的数据类型的长度

问题描述 如何得到一个dataset中某一个表的字段的名称和该数据的数据类型的长度(因为sizeof())不能用) 解决方案 解决方案二:这个简单啊,网上搜一下就得到答案了.

2000条你应知的WPF小姿势 基础篇<78-81 Dialog/Location/WPF设备无关性>

原文:2000条你应知的WPF小姿势 基础篇<78-81 Dialog/Location/WPF设备无关性> 在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师.最为出色的是他维护了两个博客:2,000Things You Should Know About C#  和 2,000 Things You Should Know About WPF .他以类似微博式的150字简短语言来每天更新一条WPF和C#重要又容易被遗忘的知识.很希望能够分享给大家. 本系列

《UNIX网络编程 卷1:套接字联网API(第3版)》——1.3 协议无关性

1.3 协议无关性 图1-5中的程序是与IPv4协议相关的:我们分配并初始化一个sockaddr_in类型的结构,把该结构的协议族成员设置为AF_INET,并指定socket函数的第一个参数为AF_INET. 为了让图1-5中的程序能够在IPv6上运行,我们必须修改这段代码.图1-6所示的是一个能够在IPv6上运行的版本,其中改动之处用加粗的等宽字体突出显示. 我们只修改了程序的5行代码,得到的却是另一个与协议相关的程序:这回是与IPv6协议相关的.更好的做法是编写协议无关的程序.图11-11将

浅析目标市场的两大特性:可定位性和可营销性

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 互联网的快速发展为我们提供了各种各样的便利,但对于很多站长来说同时也是一种压力,因为大量日常消费品的竞争已经达到白热化,所以部分站长选择了相对容易进入的利基市场.不过找到一个利基市场后,还不能马上进入,必须考虑这个目标市场是否在网上?用户是否能集中定位?是否真的有用户存在?总体来说就是目标市场的两大特性:可定位性和可营销性. 首先,可定位性:

发现一个有意思的bbs网站,发现一个Waves开源项目

本文的原文连接是: http://blog.csdn.net/freewebsys/article/details/51619608 未经博主允许不得转载. 博主地址是:http://blog.csdn.net/freewebsys 1,页面样式 和google风格的样式,并且在页面加载完成之后还会有顶部的颜色条变换,非常好看. 下拉菜单也很好看. https://bbs.gitlab.cc/ 上面有过开关,能够把菜单固定住 2,查看了下css 从里面刨出来两个项目. 一个叫waves不知道和g

一个有意思的递归定义

最近在看一本<WEB全栈工程师的自我修养>一书,其中涉及到了npm这个词的意义,非常有意思. 一般人可能以为npm是Node Package Manager的缩写,但实际上不是这样的,npm不是Node Package Manager的首字母缩写,所以不能全大写.npm是"npm is not an acronym"(npm不是一个缩写)这个递归定义的简写. 是不是很绕?呵呵. 递归定义是指一种在定义中引用他自身的定义方法,在程序中引用自己称为递归,因为自身是递归的,所以无

php中一个有意思的日期逻辑处理_php技巧

今天处理了一个很小的问题. 需求是这样的,从周一到周日只能看到上周一到上周日的数据. 这里直接从数据库里根据 date 字段查询 范围即可. 但需要PHP生成 开始日期和结束日期. 最开始,我直接这么处理. 复制代码 代码如下: $start_date = date('Y-m-d' , strtotime("-2 week monday")); $end_date = date('Y-m-d' , strtotime("$start_date +6 day"));