参考文档:

Spring Boot 中使用 thrift 入门
springboot整合Thrift

1. 什么是 Thrift

Thrift 是一种接口描述语言和二进制通讯协议,它被用来定义和创建跨语言的服务。它被当作一个远程过程调用(RPC)框架来使用,以前是由 Facebook 开发的,但它现在是 Apache 软件基金会的开源项目了。

2. Thrift 架构

Thrift 包含一套完整的栈来创建客户端和服务端程序。顶层部分是由 Thrift 定义生成的代码。而服务则由这个文件客户端和处理器代码生成。在生成的代码里会创建不同于内建类型的数据结构,并将其作为结果发送。协议和传输层是运行时库的一部分。有了 Thrift,就可以定义一个服务或改变通讯和传输协议,而无需重新编译代码。除了客户端部分之外,Thrift 还包括服务器基础设施来集成协议和传输,如阻塞、非阻塞及多线程服务器。栈中作为 I/O 基础的部分对于不同的语言则有不同的实现,如下官方示意图

thrift 架构

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