Learning four basic knowledge on Apache Thrift official website

Four serialization mechanism

4.1 basic knowledge

  • Thrift supports serialization and deserialization of binary, compressed format, and json format data. Developers can choose the specific form of the protocol more flexibly. The protocol is freely extensible. The new version of the protocol is fully compatible with the old version!
  • Previously, we introduced some basic knowledge of protocol. Let's take a detailed look at its usage

4.2 TProtocol

  • This is a protocol interface. We can see how many implementation classes it has

  • TBinaryProtocol: it is the default protocol of Thrift. It uses binary coding format for data transmission and basically sends the original data directly
  • TCompactProtocol: compressed and dense data transmission protocol, zigzag coding format based on variable length quantity
  • TJSONProtocol: use JSON (JavaScript Object Notation) data encoding protocol for data transmission
  • TDebugProtocol: it is often used by coders to test and present it in the form of text for easy reading

Basic method

  /**
   * Writing methods. Writing method
   */

  public abstract void writeMessageBegin(TMessage message) throws TException;

  public abstract void writeMessageEnd() throws TException;

  public abstract void writeStructBegin(TStruct struct) throws TException;

  public abstract void writeStructEnd() throws TException;

  public abstract void writeFieldBegin(TField field) throws TException;

  public abstract void writeFieldEnd() throws TException;

  public abstract void writeFieldStop() throws TException;

  public abstract void writeMapBegin(TMap map) throws TException;

  public abstract void writeMapEnd() throws TException;

  public abstract void writeListBegin(TList list) throws TException;

  public abstract void writeListEnd() throws TException;

  public abstract void writeSetBegin(TSet set) throws TException;

  public abstract void writeSetEnd() throws TException;

  public abstract void writeBool(boolean b) throws TException;

  public abstract void writeByte(byte b) throws TException;

  public abstract void writeI16(short i16) throws TException;

  public abstract void writeI32(int i32) throws TException;

  public abstract void writeI64(long i64) throws TException;

  public abstract void writeDouble(double dub) throws TException;

  public abstract void writeString(String str) throws TException;

  public abstract void writeBinary(ByteBuffer buf) throws TException;

  /**
   * Reading methods. Reading method
   */

  public abstract TMessage readMessageBegin() throws TException;

  public abstract void readMessageEnd() throws TException;

  public abstract TStruct readStructBegin() throws TException;

  public abstract void readStructEnd() throws TException;

  public abstract TField readFieldBegin() throws TException;

  public abstract void readFieldEnd() throws TException;

  public abstract TMap readMapBegin() throws TException;

  public abstract void readMapEnd() throws TException;

  public abstract TList readListBegin() throws TException;

  public abstract void readListEnd() throws TException;

  public abstract TSet readSetBegin() throws TException;

  public abstract void readSetEnd() throws TException;

  public abstract boolean readBool() throws TException;

  public abstract byte readByte() throws TException;

  public abstract short readI16() throws TException;

  public abstract int readI32() throws TException;

  public abstract long readI64() throws TException;

  public abstract double readDouble() throws TException;

  public abstract String readString() throws TException;

  public abstract ByteBuffer readBinary() throws TException;

4.3 TCompactProtocol

  • Tcompactprotocol 2 is a Java implementation of the compact protocol specified in THRIFT-110. The basic way to reduce structure overhead is to a) use variable length integers everywhere, and b) use unused bits as much as possible.
  • Your savings will obviously vary according to the specific composition of the structure, but in general, the more fields, nested structures, short strings and collections, and low value i32 and i64 fields you have, the more benefits you will see.
  • All types:
/**
   * All of the on-wire type codes.
   */
  private static class Types {
    public static final byte BOOLEAN_TRUE   = 0x01;
    public static final byte BOOLEAN_FALSE  = 0x02;
    public static final byte BYTE           = 0x03;
    public static final byte I16            = 0x04;
    public static final byte I32            = 0x05;
    public static final byte I64            = 0x06;
    public static final byte DOUBLE         = 0x07;
    public static final byte BINARY         = 0x08;
    public static final byte LIST           = 0x09;
    public static final byte SET            = 0x0A;
    public static final byte MAP            = 0x0B;
    public static final byte STRUCT         = 0x0C;
  }

Source code analysis

package com.example.thrift.client;

import com.example.thrift.thrift.person;
import com.example.thrift.thrift.personservice;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.layered.TFramedTransport;


/**
 * @Author shu
 * @Description Customer service end
 **/
public class ThriftClient {
    public static void main(String[] args) {
        TTransport transport =null;
        try {
            // connect
            transport = new TFramedTransport(new TSocket("127.0.0.1",8803),600);
            // agreement
            TProtocol protocol = new TCompactProtocol(transport);
            // Call method
            personservice.Client client = new personservice.Client(protocol);
            // open a connection
            transport.open();
            // Call method
            person result = client.getPersonInfoByUserNmae("Ha ha ha ha");
            System.out.println("Result =: " + result);
        } catch (TException e) {
            e.printStackTrace();
        } finally {
            if (null != transport) {
                transport.close();
            }
        }

    }
}
  • Click our custom method getPersonInfoByUserNmae to see the service generated by thrift
 public person getPersonInfoByUserNmae(String username) throws personexception, org.apache.thrift.TException
    {
      send_getPersonInfoByUserNmae(username);
      return recv_getPersonInfoByUserNmae();
    }
    

public void send_getPersonInfoByUserNmae(String username) throws org.apache.thrift.TException
    {
      getPersonInfoByUserNmae_args args = new getPersonInfoByUserNmae_args();
      args.setUsername(username);
      // Key method: sending data
      sendBase("getPersonInfoByUserNmae", args);
    }
  • After entering the sendBase method, you can see that it actually calls the implementation method of TCompactProtocol
 protected void sendBase(String methodName, TBase<?,?> args) throws TException {
    sendBase(methodName, args, TMessageType.CALL);
  }

// Write the data into the specific implementation protocol
private void sendBase(String methodName, TBase<?,?> args, byte type) throws TException {
    // Write start, protocol basic information
    oprot_.writeMessageBegin(new TMessage(methodName, type, ++seqid_));
    // write in
    args.write(oprot_);
    // Write end
    oprot_.writeMessageEnd();
    // refresh data
    oprot_.getTransport().flush();
  }

 /**Write the message header to the line. The compact protocol message contains the protocol version
   * Write a message header to the wire. Compact Protocol messages contain the
   * protocol version so we can migrate forwards in the future if need be.
   */
  @Override
  public void writeMessageBegin(TMessage message) throws TException {
      // Agreement No
    writeByteDirect(PROTOCOL_ID);
      // edition
    writeByteDirect((VERSION & VERSION_MASK) | ((message.type << TYPE_SHIFT_AMOUNT) & TYPE_MASK));
      // serial number
    writeVarint32(message.seqid);
      // Message name
    writeString(message.name);
  }
  • General basic interface of generated Thrift object: TSerializable
public interface TSerializable {

  /**
   * Reads the TObject from the given input protocol.
   *Read object from protocol
   * @param iprot Input protocol
   */
  public void read(TProtocol iprot) throws TException;

  /**
   * Writes the objects out to the protocol
   *Write object to protocol
   * @param oprot Output protocol
   */
  public void write(TProtocol oprot) throws TException;

}

  • Obviously, this calls the method generated by thrift
 public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }


  • Call the TCompactProtocol method to start writing
    public void write(org.apache.thrift.protocol.TProtocol oprot, getPersonInfoByUserNmae_args struct) throws org.apache.thrift.TException {
        struct.validate();
        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.username != null) {
            
          oprot.writeFieldBegin(USERNAME_FIELD_DESC);
            
          oprot.writeString(struct.username);
            
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        
        oprot.writeStructEnd();
      }

    }
  • Different from the write method, the read method calls the read implementation class of the TSerializabl interface. In fact, it also calls the methods in the service generated by thrift.

public interface IScheme<T extends TBase> {

  public void read(org.apache.thrift.protocol.TProtocol iproto, T struct) throws org.apache.thrift.TException;

  public void write(org.apache.thrift.protocol.TProtocol oproto, T struct) throws org.apache.thrift.TException;

}

Keywords: Java Apache thrift

Added by ravnen on Sun, 06 Mar 2022 15:30:13 +0200