参考文档:
Spring Boot 中使用 thrift 入门
springboot整合Thrift
1. 什么是 Thrift
Thrift 是一种接口描述语言和二进制通讯协议,它被用来定义和创建跨语言的服务。它被当作一个远程过程调用(RPC)框架来使用,以前是由 Facebook 开发的,但它现在是 Apache 软件基金会的开源项目了。
2. Thrift 架构
Thrift 包含一套完整的栈来创建客户端和服务端程序。顶层部分是由 Thrift 定义生成的代码。而服务则由这个文件客户端和处理器代码生成。在生成的代码里会创建不同于内建类型的数据结构,并将其作为结果发送。协议和传输层是运行时库的一部分。有了 Thrift,就可以定义一个服务或改变通讯和传输协议,而无需重新编译代码。除了客户端部分之外,Thrift 还包括服务器基础设施来集成协议和传输,如阻塞、非阻塞及多线程服务器。栈中作为 I/O 基础的部分对于不同的语言则有不同的实现,如下官方示意图
3. 支持的通讯协议
- TBinaryProtocol
一种简单的二进制格式,简单,但没有为空间效率而优化。比文本协议处理起来更快,但更难于调试。 - TCompactProtocol
更紧凑的二进制格式,处理起来通常同样高效。 - TDebugProtocol
一种人类可读的文本格式,用来协助调试。 - TDenseProtocol
与TCompactProtocol类似,将传输数据的元信息剥离。 - TJSONProtocol
使用JSON对数据编码。 - TSimpleJSONProtocol
一种只写协议,它不能被Thrift解析,因为它使用JSON时丢弃了元数据。适合用脚本语言来解析
4. 支持的传输协议
- TFileTransport
该传输协议会写文件。 - TFramedTransport
当使用一个非阻塞服务器时,要求使用这个传输协议。它按帧来发送数据 - TMemoryTransport
使用存储器映射输入输出。(Java 的实现使用了一个简单的 ByteArrayOutputStream) - TSocket
使用阻塞的套接字I/O来传输。 - TZlibTransport
用 zlib 执行压缩。用于连接另一个传输协议。
5. 支持的服务模型
- TNonblockingServer
一个多线程服务器,它使用非阻塞 I/O(Java的实现使用了 NIO 通道)。TFramedTransport 必须跟这个服务器配套使用。 - TSimpleServer
一个单线程服务器,它使用标准的阻塞 I/O。测试时很有用。 - TThreadPoolServer
一个多线程服务器,它使用标准的阻塞 I/O - THsHaServer
YHsHa 引入了线程池去处理(需要使用 TFramedTransport 数据传输方式),其模型把读写任务放到线程池去处理; Half-sync/Half-async(半同步半异步)的处理模式; Half-sync 是在处理 IO 时间上(sccept/read/writr io), Half-async 用于 handler 对 RPC 的同步处理。
6. SpringBoot 整合 Thrift
6.1 准备
安装 thrift
brew install thrift
thrift -version
添加 maven 依赖
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.5.0-fix-thrift1190</version>
</dependency>
- 依赖版本需要与安装的 thrift 版本一致
编写 thrift 文件
hello.thrift
namespace java com.rs.thriftserver
service Hello{
string helloString(1:string param)
}
使用 thrift 工具生成 java 代码
thrift -r -gen java hello.thrift
将代码放置到 client 服务和 server 服务
6.2 Service 端
编写服务实现类
public class HelloService implements Hello.Iface {
@Override
public String helloString(String param) throws TException {
return "hello " + param;
}
}
编写服务端
@SpringBootApplication
public class ThriftServerApplication {
public static void main(String[] args) throws TTransportException {
SpringApplication.run(ThriftServerApplication.class, args);
Processor processor = new Processor(new HelloService());
TServerSocket serverTransport = new TServerSocket(8888);
TSimpleServer server = new TSimpleServer(processor, serverTransport, new TTransportFactory(),
new TBinaryProtocol.Factory());
server.serve();
}
}
6.3 Client 端
@SpringBootApplication
public class ThriftClientApplication {
public static void main(String[] args) throws TException {
SpringApplication.run(ThriftClientApplication.class, args);
TSocket transport = new TSocket("localhost", 8888);
// 协议需一致
TProtocol protocol = new TBinaryProtocol(transport);
Client client = new Client(protocol);
transport.open();
String result = client.helloString("rainsheep");
System.out.println(result);
}
}