-
介绍
thrift是一款由facebook公布的开源rpc框架,通过一个中间语言IDL(接口定义语言)来定义RPC的数据类型和接口,这些内容写在以.thrift结尾的文件中,然后通过特殊的编译器来生成不同语言的代码,以满足不同需要的开发者,比如java开发者,就可以生成java代码,c++开发者可以生成c++代码,生成的代码中不但包含目标语言的接口定义,方法,数据类型,还包含有RPC协议层和传输层的实现代码。
thrift协议栈结构图:
thrift是一种c/s的架构体系.在最上层是用户自行实现的业务逻辑代码.第二层是由thrift编译器自动生成的代码,主要用于结构化数据的解析,发送和接收。TServer主要任务是高效的接受客户端请求,并将请求转发给Processor处理。Processor负责对客户端的请求做出响应,包括RPC请求转发,调用参数解析和用户逻辑调用,返回值写回等处理。从TProtocol以下部分是thirft的传输协议和底层I/O通信。TProtocol是用于数据类型解析的,将结构化数据转化为字节流给TTransport进行传输。TTransport是与底层数据传输密切相关的传输层,负责以字节流方式接收和发送消息体,不关注是什么数据类型。底层IO负责实际的数据传输,包括socket、文件和压缩数据流等。
下图是client/server的调用流程:
-
安装(mac版)
brew install thrift
基于netty的thrift实现
thrift与其他protobuf类似,只是在IDL语法方面有不同,同时thrift更为强大,支持语言更多样。接下来对thrift进行简单的实现
struct相当于protobuf中的message,除此之外,thrift还提供了exception、service等更为丰富的object。
.thrift文件
namespace java thrift.generated
namespace py py.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 date
}
service PersonService {
Person getPersonByUsername(1: required String username) throws (1: DataException dataException),
void savePerson(1: required Person person) throws (1: DataException dataException)
}
struct相当于protobuf中的message,除此之外,thrift还提供了exception、service等更为丰富的object。
personService实现类编写:
public class PersonServiceImpl implements PersonService.Iface {
@Override
public Person getPersonByUsername(String username) throws DataException, TException {
System.out.println("get Client param : " + username);
Person person = new Person();
person.setUsername(username);
person.setAge(20);
person.setMarried(false);
return person;
}
@Override
public void savePerson(Person person) throws DataException, TException {
System.out.println("get Client param : " );
System.out.println(person.getUsername());
System.out.println(person.getAge());
System.out.println(person.isMarried());
}
}
服务器端编写:
public class NiftyServer {
public static void main(String[] args) {
PersonService.Iface serviceInterface = new PersonServiceImpl();
TProcessor processor = new PersonService.Processor<>(serviceInterface);
ThriftServerDef serverDef = new ThriftServerDefBuilder().listen(8899).withProcessor(processor).build();
final NettyServerTransport server = new NettyServerTransport(serverDef);
server.start();
System.out.println("服务器启动成功...");
}
}
客户端编写:
public class NiftyClient {
public static void main(String[] args) throws Exception{
TTransport transport = new TSocket("localhost",8899);
transport.open();
TProtocol protocol = new TBinaryProtocol(transport);
PersonService.Client client = new PersonService.Client(protocol);
Person person = client.getPersonByUsername("张三");
System.out.println(person.getUsername());
System.out.println(person.getAge());
System.out.println(person.isMarried());
System.out.println("-----------");
Person person1 = new Person();
person1.setUsername("李四");
person1.setAge(30);
person1.setMarried(true);
client.savePerson(person1);
transport.close();
}
}
实现结果如下:服务器端输出
客户端输出: