Apache Thrift learning (3): principle and architecture analysis

Basic structure

From the previous article on learning  Apache Thrift (2): Getting started with Thrift , the demo can basically get the architecture shown in the following figure:

Your Code represents the business code of the client and server

XXXService.Client: The client object that connects and communicates with the server, and is used to call the method of the [Service] interface. Service here refers to the Service interface layer generated by Thrift

XXX.write()/read(): is the code generated by Thrift, write() is to write data to the server through the socket, and read() is to receive data from the server through the socket. The relevant code generated by Thrift is as follows:

The client sample code is as follows:

package com.leolee.thrift.person;

import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;

/**
 * @ClassName ThriftClient
 * @Description: Thrift 客户端
 * @Author LeoLee
 * @Date 2020/9/6
 * @Version V1.0
 **/
public class ThriftClient {

    public static void main(String[] args) {

        //服务端transport用的是TFramedTransport,客户端也要用TFramedTransport
        TTransport transport = new TFramedTransport(new TSocket("127.0.0.1", 8899), 60);//对应服务端的传输层方法[TFramed]
        TProtocol protocol = new TCompactProtocol(transport);//对应服务端的协议层方法[TCompact]
        PersonService.Client client = new PersonService.Client(protocol);

        try {
            //打开连接
            transport.open();
            Person person = client.getPersonByName("LeoLee");
            System.out.println("打印getPersonByName请求结果:");
            System.out.println(person.getName());
            System.out.println(person.getAge());
            System.out.println(person.isMarried());

            System.out.println("------------------------");

            Person person2 = new Person();
            person2.setName("LeoLee");
            person2.setAge(25);
            person2.setMarried(false);
            client.savePerson(person2);

        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        } finally {
            transport.close();
        }

    }
}

In this example, the PersonService.Client object calls the getPersonByName and  savePerson methods of the service layer respectively . Take getPersonByName as an example to view the code generated by Thrift:

There must be send_xxx() and recv_xxx() . One of these two methods is responsible for writing and the other is responsible for reading .

send_xxx:

recv_xxx:

In the end , read and write of TSerializable will be called

TProtocol: Protocol layer (application layer), which determines what data format is used for data transmission, and emphasizes the data format.

TTransport: Transport layer

Underlying I/O: The actual network I/O is used to transfer data, which is transferred between the client and the server in bytecode

The client and the server use the above process to execute from top to bottom and read and write to each other. The above architecture is not limited to Thrift, the general RPC architecture is similar in principle

Transmission format

  • TBinaryProtocol: The binary format is definitely smaller and more efficient than the text format.
  • TCompactProtocol: It is more efficient than TbinaryProtocol, and further compresses binary data into a "more compact" data format
  • TJSONProtocol: text format, JSON format data
  • TSimpleJSONProtocol: It is rarely used and provides a JSON write-only protocol. Simply put, this is a format that lacks source data information. After the data is converted to this format, it cannot be on the opposite end (server or client) Then reverse analysis into source data. Its content can be parsed by scripting language. ( To be honest, the last one is parsed by a scripting language. I don’t understand what the hell is going on. I checked SimpleJSON, it is probably a json format that cannot parse the field data type )
  • TDebugProtocol: Data debugging format, an easy-to-understand text format that is readable by the naked eye to facilitate multi-terminal debugging (packet interception during data transmission, analysis of data structure during transmission, etc.)

Data transmission method

  • TSocket: The least used, blocking socket
  • TFramedTransport: use frame as a unit for transmission, used in non-blocking services. This transmission method divides the transmitted data into a frame
  • TFileTransport: transfer in file form
  • TMemoryTransport: Use memory for I/O. In the implementation of Thrift JAVA, a simple ByteArrayOutputStream is actually used internally
  • TZlibTransport: Use Zlip to compress data and use it in conjunction with other transmission methods. There is currently no JAVA implementation.

Supported service model

TSimpleServer: Simple single-threaded service model, often used for testing

TThreadPoolServer: Multi-threaded service model, using standard blocking IO (similar to a JAVA dynamic thread pool, when a request arrives at the server, a thread will be allocated for this request, when it is used, it will be released when the thread pool It will be created when it is not enough, and it will also be recycled when there are idle threads)

TNonblockingServer: Multi-threaded service model, using non-blocking IO (need to cooperate with TFrameTransport data transmission mode)

THsHaServer: THsHa introduces a thread pool for processing. Its model puts the read and write tasks in the thread pool for processing, provides Half-sync/Half-async processing mode, Half-sync handles IO events (accept/read/write io), alf -async is used for the synchronous processing of RPC by the handler

Those who need code come here to get it: demo project address

Guess you like

Origin blog.csdn.net/qq_25805331/article/details/108470793