thrift文件编写

data.thrift

namespace java  thrift.generated

typedef i16 short
typedef i32 int
typedef i64 long
typedef bool boolean
typedef string String

struct Person {
    1:optional String username,
    2:optional int age,
    3:optional boolean married
}

exception DataException {
    1:optional String message,
    2:optional String callStack,
    3:optional String data
}

service PersonService {
    Person getPersonByUsername(1:required String username) throws (1:DataException dataException),

    void savePerson(1:required Person person) throws (1:DataException dataException)
}

typedef:在一个文件内将类型重命名使用
strut : 结构体
exception:方法调用过程中可能会发生的异常
service: 类似mvc中的controller,提供方法调用
与protobuf的tag num (=n)相较 ,thrift用在开头 并用:代替了=号,
xxx=1 1:xxx

使用编译器

thrift --gen java data.thrift

服务接口的实现

PersonServiceImpl

/**
 *  services接口中定义的两个函数
*/
public class PersonServiceImpl implements PersonService.Iface {
    @Override
    public Person getPersonByUsername(String username) throws DataException, TException {
        System.out.println("get person param:" + username);
        Person person = new Person();
        person.setAge(23);
        person.setUsername(username);
        person.setMarried(false);

        return person;
    }

    @Override
    public void savePerson(Person person) throws DataException, TException {
        System.out.println("get client param:");
        System.out.println(person.getAge());
        System.out.println(person.getUsername());
        System.out.println(person.isMarried());
    }
}

服务端

ThriftServer

public class ThriftServer {
    public static void main(String[] args) throws Exception{
        TNonblockingServerSocket socket = new TNonblockingServerSocket(8899);
        THsHaServer.Args arg = new THsHaServer.Args(socket).minWorkerThreads(2).maxWorkerThreads(4);
        PersonService.Processor<PersonServiceImpl> processor = new PersonService.Processor<>(new PersonServiceImpl());

        arg.protocolFactory(new TCompactProtocol.Factory());
        arg.transportFactory(new TFramedTransport.Factory());
        arg.processorFactory(new TProcessorFactory(processor));

        TServer server = new THsHaServer(arg);
        System.out.println("thrift server started");
        server.serve();
    }
}

TFramedTransport表示的是传输层用到的对象
TCompactProtocol表示协议层用到的对象
THsHaServer半阻塞半同步
serve服务端循环监听

客户端

ThriftClient

public class ThriftClient {
    public static void main(String[] args) {
        TTransport tTransport = new TFramedTransport(new TSocket("localhost",8899),600);
        TProtocol tProtocol = new TCompactProtocol(tTransport);
        PersonService.Client client = new PersonService.Client(tProtocol);

        try{
            tTransport.open();
            Person person = client.getPersonByUsername("shafish");

            System.out.println(person.getUsername());
            System.out.println(person.getAge());
            System.out.println(person.isMarried());

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

            Person person2 = new Person();

            person2.setMarried(true);
            person2.setUsername("SHAFISH");
            person2.setAge(22);

            client.savePerson(person2);
        } catch (Exception e){
            throw new RuntimeException(e.getMessage(),e);
        } finally {
            tTransport.close();
        }
    }
}

600超时时间

Thrift传输格式

  • TBinaryProtocol: 二进制格式
  • TCompactProtocol: 压缩格式
  • TJSONProtocol: json格式
  • TSimpleJSONProtocol: 提供json的只写协议,生成的文件很容易通过脚本语言解析
  • TDebugProtocol: 使用易懂的可读文本格式,便于debug

Thrift数据传输方式 -- 传输层使用

  • TSocket: 阻塞式socket
  • TFramedTransport: 以frame为单位进行传输,非阻塞式服务中使用
  • TFileTransport: 以文件形式进行传输
  • TMemoryTransport: 将内容用于io,java使用ByteArrayOutputStream进行内部实现
  • TZlibTransport: 使用zlib进行压缩,与其他传输方式联合使用

Thrift支持的服务模型

  • TSimpleServer: 简单的单线程服务模型,常用于测试
  • TThreadPoolServer: 多线程服务模型,使用标准的阻塞式IO
  • TNonblockingServer: 多线程服务模型,使用非阻塞式IO(需要用TFrameTransport数据传输方式)
  • THsHaServer: THsHa把读写任务放到线程池进行处理

result