数据传输的痛点和需求

  • 数据交换网络通信的场景中,存在的痛点在于 数据的体积大小 ,以及传输完成后 解析数据的速度

protobuf 的效率

  • protobuf 序列化后是json的10分之一,xml的20分之一,但是性能是它们的5~100倍。
  • 我们横向对比下两种格式
    • JSON 格式
    {
    	"id":1,
    	"name":"czh",
    	"hobby":"coding"
    	"introduction":"hello world"
    }
    
    • XML格式
      <id>1<id>
      <name>czh<name>
      <hobby>coding<hobby>
      <introduction>hello world</introduction>
      

protobuf 传输体积小的原因

  • IDL(Interface Description Languange)来表示要传输的数据

    message Person {
        required int32 id = 1;
        required string name = 2;
        required string hobby = 3;
        required string introduction = 4;
    } 
    
  • protobuf 传输体积比XML和JSON要小在于没有将 idnamehobbyintroduction 放到要传输的数据里面。
    | 1 | czh | coding | hello world |
    | ---- | ---- | ------ | ----------- |

  • 通信的两方会同时维护这个文件

  • 这样又会引出一个问题 ---> 后三个字符串分别属于哪一个字段?

    • tag 对每一个字段进行区分
      |TAG 1|TAG chz|TAG coding|TAG hello world|
      |-------|-------|-------|-------|
    • makeTag 函数
      static int makeTag(final int fieldNumber, final int wireType){
          return (fieldNumber << 3) | wireType;
      }
      

      该函数会传入一个fieldNumber,和一个 wireType
      返回值是将 fieldNumber 左移三位,并且 或上 wireType
      |Type|Meaning|Used For|
      |-------|-------|-------|
      |0|Varint|int32,int64,uint32,uint64,sint32,sint64,bool,enum|
      |1|64-bit|fixed64,sfixed64,double|
      |2|Length=delimited|string,bytes,embedded messages,packed repeated fields
      |3|Start group|groups(deprecated)|
      |4|End group| groups(deprecated)|
      |5|32-bit| fixed32,sfixed32,float|

      • 上表是 wireType的数据范围。
        Protobuf 支持 0~5 的数据,用二进制表示就是 000~101
        fieldNumber 左移空出来的三位可以用 wireType填补。