thrift使用和源码分析

1 前言

thrift的官方文档比较差,很多细节没有介绍清楚,比如require、optional和default字段的区别是什么,为什么字段前面要写序号等,带着这些疑问,我们需要阅读生成的源码来了解具体细节。另外thrift的非官方文档可以参考这篇:http://diwakergupta.github.io/thrift-missing-guide

2 network stack

thrif的网络栈在官网已经介绍的比较清楚了,分为4层,从下往上依次是:

newwork stack

  1. Transport。提供网络IO的简单抽象
  2. Protocol。用于编解码,将底层的字节编码成二进制、JSON等;Protocol层用于对模式编码以及负责序列化
  3. Processor。封装了从Protocol读写的功能,可以理解为用户的业务逻辑所在地
  4. Server。代码一个服务端,将Transport、Protocol、Processor整合起来,等待请求到来并处理

3 简单使用

3.1 thrift安装

thrift的安装按照官网的教程或者网上其他教程来就行了,这里安装的是thrift的0.8.0版本, 安装完后可以使用命令查看安装的thrift版本

thrift -version

3.2 编写IDL

创建文件mythrift.thrift,在里面编写如下内容

namespace java com.learn.learnthrift

 struct Stu {
 1:i32 name = 13
 2:required i32 age
 3:optional i32 height = 23
 }

 struct Teacher {
 1:string name = "13"
 2:required string age = "14"
 3:optional string height = "15"
 }

 service MyService {
     void printStu(1:Stu stu, 2:Teacher teacher)
     void printStu2(1:Stu stu, 2:Teacher teacher)
 }

3.3 生成java代码

运行命令,生成java代码,然后将生成的代码拷贝进项目即可使用,其中mythrift.thrift就是刚才我们编写的IDL文件。运行命令后会在mythrift.thrift所在的目录生成gen-javabean文件夹,其内容就是我们生成java文件

thrift --gen java:beans mythrift.thrift

生成的文件如下:

gen-javabean

3.4 编写代码

将生成的代码copy到项目中,其中红框框起来的是thrift生成的文件,其他的是需要我们编写的代码

project

DemoClient.java

public class DemoClient {
    public static void main(String[] args) throws Exception{
        // 创建Transport
        TTransport transport = new TSocket("localhost", 9090, 5000);
        //创建protocol
        TProtocol protocol = new TBinaryProtocol(transport);

        //创建客户端
        MyService.Client client = new MyService.Client(protocol);
        transport.open();

        Stu stu = new Stu();
        stu.setAge(23);

        Teacher teacher = new Teacher("jack", "32");
        client.printStu(stu, teacher);

        transport.close();
    }
}

DemoServer.java

public class DemoServer {
    public static void main(String[] args) throws Exception{
        // 创建processor
        TProcessor tProcessor = new MyService.Processor<MyService.Iface>(new MyServiceImpl());
        //创建protocol
        TProtocolFactory tProtocolFactory = new TBinaryProtocol.Factory();

        // 创建transport, TServerSocket继承自TTransport
        TServerSocket tServerSocket = new TServerSocket(9090);
        //创建server参数
        TServer.Args tArgs = new TServer.Args(tServerSocket);
        tArgs.processor(tProcessor);
        tArgs.protocolFactory(tProtocolFactory);

        // 创建TServer
        TServer tServer = new TSimpleServer(tArgs);
        tServer.serve();
    }
}

MyServiceImpl.java

public class MyServiceImpl implements MyService.Iface {
    @Override
    public void printStu(Stu stu, Teacher teacher) throws TException {
        System.out.println(stu);
        System.out.println("name:" + stu.getName());
        System.out.println("age:" + stu.getAge());
        System.out.println("height:" + stu.getHeight());

        System.out.println("nameset: " + stu.isSetName());
        System.out.println("ageset: " + stu.isSetAge());
        System.out.println("height: " + stu.isSetHeight());
    }

    @Override
    public void printStu2(Stu stu, Teacher teacher) throws TException {
        System.out.println("printStu2 : " + stu);
    }
}

然后分别运行DemoServer和DemoClient就可以了,这就是简单的RPC通信

4 源码阅读

猜你喜欢

转载自www.cnblogs.com/set-cookie/p/9381472.html