rpc协议中,字段值类型改变的思考

背景

今天遇到了一个场景,下游强行把某个字段的类型给改了(字段顺序没有变),上线的过程中上下游都没有出错,和我预想的不一样,我认为上游反序列化解析的时候会出错

python语言,thrift协议

当然这样的做法不推荐,这里只说明一下上游没有报错的原因

代码

框架上:
用的是thrift,当然是公司封装了一层,对于我rpc client,也就是上游,影响的代码如下

      elif fid == 11:
        if ftype == TType.I64:
          self.xxx = iprot.readI64();
        else:
          iprot.skip(ftype)

这里意思是说第11个字段如果类型是int64就给对应的xxx字段赋值

但是现在rpc底层已经把这个字段改成了i32,协议变了上游怎么支持的呢?

原因就在else里面
ftype表示读到反序列化时,下个字段的类型
当读到的ftype和约定的(i64)不一样的时候,进入else逻辑,skip掉
skip的实现是什么呢?
其实就是空读接下来这个ftype的类型值,并没有任何赋值行为
避免泄密只给一点点demo,比如

    elif type == TType.STRING:
      self.readString()

综上,也就是说

下游返回第11个字段的数据类型是i32的
上游按照读到第11个字段的真实数据类型是i32的
上游按老的协议认为第11个字段应该是i64的
走到else逻辑,空读一个i32字段,并不给struct的某个字段赋值
没有报错

原因分析

业务上:
改动的字段类型对应上游的一个新功能,还没有调用量,不会报错

代码上:
框架rpc client解析代码有容错,某一个字段和预期的类型不一样可以跳过,也就是skip掉,此时只有这一个字段不能解析,不影响其他字段的获取

总结

本文讲了下rpc在下游协议没有兼容上游的情况下,上游如何减小报错损失(这里是顺序不改动,只是一个字段类型变了),影响只会细化到对象的某一个字段

总的来说,下游都应该兼容上游的,这种改动方式并不提倡。

你可能感兴趣的:(rpc协议中,字段值类型改变的思考)