最近开发的一个项目,后端采用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 {
: i16 age = ,
: string name,
: bool sex,
: double salary,
: byte childrenCount
}

IDL生成的具体语言的源代码中,解析对象时,同样也只看序号,以c#生成的代码为例:

    public void Read (TProtocol iprot)
{
iprot.IncrementRecursionDepth();
try
{
TField field;
iprot.ReadStructBegin();
while (true)
{
field = iprot.ReadFieldBegin();
if (field.Type == TType.Stop) {
break;
}
switch (field.ID)
{
case :
if (field.Type == TType.I16) {
Age = iprot.ReadI16();
} else {
TProtocolUtil.Skip(iprot, field.Type);
}
break;
case :
if (field.Type == TType.String) {
Name = iprot.ReadString();
} else {
TProtocolUtil.Skip(iprot, field.Type);
}
break;
case :
if (field.Type == TType.Bool) {
Sex = iprot.ReadBool();
} else {
TProtocolUtil.Skip(iprot, field.Type);
}
break;
case :
if (field.Type == TType.Double) {
Salary = iprot.ReadDouble();
} else {
TProtocolUtil.Skip(iprot, field.Type);
}
break;
case :
if (field.Type == TType.Byte) {
ChildrenCount = iprot.ReadByte();
} else {
TProtocolUtil.Skip(iprot, field.Type);
}
break;
default:
TProtocolUtil.Skip(iprot, field.Type);
break;
}
iprot.ReadFieldEnd();
}
iprot.ReadStructEnd();
}
finally
{
iprot.DecrementRecursionDepth();
}
}

从上面的case语句可以很清楚的看出,代码内部只认数字序号,不关心名称。

结论:只要不改变struct内部的成员类型和数字编号,struct对应的类名可以放心大胆的修改。

最新文章

  1. Lamp源码搭建
  2. bzoj3142
  3. 优秀it博客和文章
  4. [Java聊天室server]实战之五 读写循环(服务端)
  5. MLAPP——概率机器学习知识汇总
  6. Azure 基础:使用 powershell 创建虚拟网络
  7. dedecms列表页调用子栏目列表,织梦首页调用栏目的子栏目标签代码
  8. Java内存原型分析
  9. ​Installing the Ranger Kafka Plug-in
  10. JS深度判断两个对象字段相同
  11. ES 应用
  12. npm是什么,用来干嘛的
  13. 将Windows下的InfluxDB、Grafana做成Windows服务
  14. 哪个中年IT男不是一边面对危机,一边咬牙硬抗【转】
  15. TensorFlow Jupyter Notebook 和matplotlib安装配置
  16. VC开发中一些问题的解决
  17. cloudera-hdfs 告警处理
  18. redis 在windows 上面的安装和使用,集群搭建
  19. day04(权限修饰符,内部类,局部内部类,匿名内部类)
  20. 原生js封装dom操作库

热门文章

  1. Maven命令行使用:mvn clean package(打包)
  2. Put your application in production
  3. JS操作未跨域iframe里的DOM
  4. position: fixed用在iframe里面失效了
  5. JavaScript基本语法(二)
  6. 屌丝giser成长记-研一篇(上)
  7. One-Time Project Recognition
  8. Java调用solrj5.5.3接口,查询数据
  9. tar解压问题gzip: stdin: not in gzip format
  10. 如何查看Windows服务器运行了多长时间