美文网首页Java 杂谈Java技术升华
Thrift(一):快速入门

Thrift(一):快速入门

作者: 聪明的奇瑞 | 来源:发表于2018-07-09 15:54 被阅读24次

    什么是 Thrift?

    • Thrift 是 Facebook 开源的一款跨语言 RPC 框架,它通过 IDL(接口描述语言) 来定义 RPC 数据类型和接口,这些内容被写在以 .thrift 结尾的文件中,然后通过编译器来生成不同语言的代码,以满足跨语言的需要

    Thrift 安装

    Mac系统

    1. 使用 brew 快速安装
    brew install thrift
    

    Window 系统

    1. 下载 Thrift.exe:http://www.apache.org/dyn/closer.cgi?path=/thrift/0.11.0/thrift-0.11.0.exe
    2. 将下载的 exe 程序重命名为 thrift.exe,并放入一个文件夹(我这放入 D 盘 Thrift 文件夹下)
    3. 配置环境变量 Path,在最后加上 D:\Thrift;
    4. 执行命令查看是否安装成功
    thrift -version
    

    如何使用 IDL 描述接口

    • 在使用 Thrift 之前,需要提供一个 .thrift 文件,其内容是使用 IDL 描述的服务接口信息
    struct User{
        1: i32 id
        2: string name
    }
    
    service UserService{
        User getUser(1:i32 uid)
    }
    
    • 上面 user.thrift 定义了了一个数据类型 User 与业务接口 UserService。然后执行下面命令使用 Thrift 编译器生成 Java 文件
    thrift -r -gen java user.thrift
    

    可用数据类型

    • bool:布尔值,对应 Java 的 boolean
    • byte:8 位有符号整数,对应 Java 的 byte
    • i16:16 位有符号整数,对应 Java 的 short
    • i32:32 位有符号整数,对应 Java 的 int
    • i64:64 位有符号整数,对应 Java 的 long
    • double:64 位浮点数,对应 Java 的 double
    • string:文本或二进制字符串,对应 Java 的 String
    • struct:定义公共的对象,在 Java 中是一个 JavaBean
    • list:对应 Java 的 ArrayList
    • set:对应 Java 的 HashSet
    • map:对应 Java 的 HashMap
    • exception:对应 Java 的 Exception
    • service:service 类型可以被继承
    • enum:枚举类型

    Thrift 网络栈

    • 下图为 Thrift 的网络栈,包含了 Transport、Protocol、Processor 层和 Server/Client 层
    Thrift 网络栈

    Transport

    • Transport 为底层网络数据读写传输数据的抽象层,Thrift 提供了如下几个常用的 Transport 实现:
      • TSocket:该 Transport 使用阻塞 Sockert 来收发数据
      • TFramedTransport:以帧形式发送数据,如果服务器使用 NIO 时就必须使用该 Transport
      • TMemoryTransp:使用内存 I/O,内部使用了 ByteArrayOutputStream
      • TZlibTransport: 使用 Zlib 压缩传输的数据,但 Java 中未实现

    Protocol

    • Protocol 为数据传输协议层,即对传输后的数据序列化和反序列化,常用的协议有:
      • TBinaryProtocol:二进制格式
      • TCompactProtocol:压缩格式
      • TJSONProtocol:JSON 格式
      • TSimpleJSONProtocol:提供 JSON 只写协议,生成的文件很容易通过脚本语言解析
      • TDebugProtocoal:生成 Text 格式,常用语调试

    Processor

    • Processor 层对象由 Thrift 根据用户 IDL 文件生成,我们通常不能指定,该层主要有两个功能:
      • 从 Protocol 层读取数据然后交给对应 Handler 处理
      • 将 Handler 处理的结果发送给 Protocol 层

    Server

    • Thrift 提供的 Server 实现有:
      • TNonblockingServer:基于多线程,非阻塞 IO 的 Server 层实现,专用于处理大量并发请求
      • THsHaServer:半同步/半异步的服务器模型
      • TThreadPoolServer:基于多线程阻塞 IO 的 Server 层实现,它消耗的系统资源比 TNonblockingServer 高,但可以提供更高的吞吐量
      • TSimpleServer: 该实现主要是用于测试. 它只有一个线程,并且是阻塞 IO, 因此在同一时间只能处理一个连接

    Thrift 快速入门

    • 以上面 user.thrift 为例,执行下面命令生成两个类 User、UserService ,将其拷贝到项目中(可能需要修改类中的包路径
    thrift -r -gen java user.thrift
    
    • Maven 引入依赖
    <dependency>
      <groupId>org.apache.thrift</groupId>
      <artifactId>libthrift</artifactId>
      <version>0.11.0</version>
    </dependency>
    
    • 编写 UserService 业务实现类
    public class UserServiceImpl implements UserService.Iface {
        @Override
        public User getUser(int uid) throws TException {
            User user = new User(uid,"ly");
            return user;
        }
    }
    
    • 编写 Server
    public class Server {
        public static void main(String[] args) throws Exception {
            // 业务处理器
            TProcessor processorr = new UserService.Processor<UserService.Iface>(new UserServiceImpl());
            // 设置服务器
            TServerSocket serverSocket = new TServerSocket(8181);
            // 传输协议为二进制
            TBinaryProtocol.Factory protocolFactory = new TBinaryProtocol.Factory();
            // 使用单线程阻塞 I/O 模型
            TServer.Args simpleArgs = new TServer.Args(serverSocket).processor(processorr).protocolFactory(protocolFactory);
            TServer server = new TSimpleServer(simpleArgs);
            System.out.println("开启Thrift服务器,监听端口:8181");
            server.serve();
        }
    }
    
    • 编写 Client
    public class Client {
        public static void main(String[] args) throws Exception {
            // 设置调用的服务地址-端口
            TTransport tTransport = new TSocket("localhost", 8181);
            // 使用二进制协议
            TProtocol protocol = new TBinaryProtocol(tTransport);
            // 使用的接口
            UserService.Client client = new UserService.Client(protocol);
            // 打开 Socket
            tTransport.open();
            System.out.println(client.getUser(123));
            tTransport.close();
        }
    }
    
    • 测试:先运行 Server,在运行 Client 可看到下面输出
    User(id:123, name:ly)
    

    相关文章

      网友评论

        本文标题:Thrift(一):快速入门

        本文链接:https://www.haomeiwen.com/subject/roktpftx.html