Apache Thrift学习(2):Thrift使用入门

安装Thrift

在官网下载编译器:https://thrift.apache.org/download

我本机是windows,下载后的文件解压出 thrift-0.13.0.exe,重命名为:thrift.exe,随便放在一个路径下即可。

配置系统变量Path:

测试安装是否成功:

.thrift 文件编写

Apache Thrift学习(1):Thrift详细介绍》中介绍了 .thrift 文件的构成,这里不在赘述,详细的文档请大家查阅官网。

//java的包名
namespace java com.leolee.thrift.person

//定义数据类型的别名
typedef i16 short
typedef i32 int
typedef i64 long
typedef bool boolean
typedef string String

struct Person {

    1: optional String name,
    2: optional int age,
    3: optional boolean married

}


//自定义异常
exception DataException {

    1: optional String msg,
    2: optional String callStack,
    3: optional String data

}

//接口
service PersonService {

    Person getPersonByName(1: required String name) throws (1: DataException dataException),

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

}

这里需要注意的是Thrift支持使用 typedef 定义类型的别名,也必须要有字段的标识符如:”1:“。在序列化数据传输中用于标识字段的属性。

生成Java code

在对应目录生成代码:

thrift --gen java src/thrift/data.thrift

该命令会通过相对路径的 .thrift 文件在当前目录下生成Java code。

生成了DataException(自定义异常)、Person(struct对应的java对象)、PersonService(业务接口层)

将生成Java文件复制到项目中,并引入项目的Thrift相关依赖:

编写客户端和服务端代码

首先完成PersonService的实现类:

package com.leolee.thrift.person.serviceImpl;

import com.leolee.thrift.person.DataException;
import com.leolee.thrift.person.Person;
import com.leolee.thrift.person.PersonService;
import org.apache.thrift.TException;

/**
 * @ClassName PersonServiceImpl
 * @Description: 实现在data.thrift中定义的接口
 * @Author LeoLee
 * @Date 2020/9/6
 * @Version V1.0
 **/
public class PersonServiceImpl implements PersonService.Iface {

    @Override
    public Person getPersonByName(String name) throws DataException, TException {//此处

        System.out.println("Got client param:" + name);

        Person person = new Person();
        person.setAge(25);
        person.setName(name);
        person.setMarried(false);

        System.out.println("getPersonByName调用成功");
        return person;
    }

    @Override
    public void savePerson(Person person) throws DataException, TException {

        System.out.println(person.getName());
        System.out.println(person.getAge());
        System.out.println(person.isMarried());
        System.out.println("savePerson调用成功");
    }
}

服务端:

package com.leolee.thrift.person;

import com.leolee.thrift.person.serviceImpl.PersonServiceImpl;
import org.apache.thrift.TProcessorFactory;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.server.THsHaServer;
import org.apache.thrift.server.TServer;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingServerSocket;
import org.apache.thrift.transport.TTransportException;

/**
 * @ClassName ThriftServer
 * @Description: thrift服务端
 * @Author LeoLee
 * @Date 2020/9/6
 * @Version V1.0
 **/
public class ThriftServer {

    public static void main(String[] args) throws TTransportException {

        TNonblockingServerSocket serverSocket = new TNonblockingServerSocket(8899);//socket通道对象创建
        THsHaServer.Args arg = new THsHaServer.Args(serverSocket).minWorkerThreads(2).maxWorkerThreads(4);
        PersonService.Processor<PersonServiceImpl> processor = new PersonService.Processor<>(new PersonServiceImpl());

        //工厂
        arg.protocolFactory(new TCompactProtocol.Factory());//协议层工厂对象,该对象会将二进制字节码,最大限度的压缩
        arg.transportFactory(new TFramedTransport.Factory());//构建Framed传输层工厂对象
        arg.processorFactory(new TProcessorFactory(processor));

        TServer server = new THsHaServer(arg);
        System.out.println("Thrift server started");

        //死循环,源源不断的接受socket中传递的请求
        server.serve();
    }
}

客户端:

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();
        }

    }
}

可以看到,与Netty的Socket通讯很相似:

  • 服务端绑定了端口号(8899)
  • 设置服务端通道通信参数并添加Service层接口
        THsHaServer.Args arg = new THsHaServer.Args(serverSocket).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);
  • 客户端设置对应服务端连接信息以及建立通道
        TTransport transport = new TFramedTransport(new TSocket("127.0.0.1", 8899), 60);
        TProtocol protocol = new TCompactProtocol(transport);
        PersonService.Client client = new PersonService.Client(protocol);

        transport.open();

运行测试

依次启动服务端和客户端

服务端:

客户端:

需要代码的来这里拿嗷:demo项目地址

猜你喜欢

转载自blog.csdn.net/qq_25805331/article/details/108449500