Thrift跨语言RPC框架

发布时间 2023-05-04 20:12:51作者: real010

最近入职需要用到Thrift框架(准确来说其实是MTThrift),记录一下学习进度。

RPC?

RPC(Remote Procedure Call,远程过程调用)可以让我们像调用本地一样发起远程调用,为我们屏蔽一些底层细节,例如序列化,编解码,网络传输等。

Thrift

Thrift是一个轻量级、跨语言的远程服务调用框架,最初由Facebook开发,后面进入Apache开源项目。它通过自身的IDL中间语言, 并借助代码生成引擎生成各种主流语言的RPC服务端/客户端模板代码。
Thrift支持多种不同的编程语言,包括C++、Java、Python、PHP、Ruby等,Thrift更多介绍可以参考Apache官网
Thrift的主要特点有:

  • 基于二进制的高性能的编解码框架
  • 基于NIO的底层通信
  • 相对简单的服务调用模型
  • 使用IDL支持跨平台调用

IDL

Thirft是一个典型的CS架构,客户端和服务端可以使用不同的语言开发。可以使用一种中间语言关联客户端和服务端的语言,将这种语言称为IDL(Interface Definition Language)。
Thrift采用IDL定义通用的服务接口,然后通过Thrift提供的编译器,将服务接口编译成为不同语言的代码,实现跨语言的功能。IDL详细介绍可以参考apache,IDL文件通常以.thrift结尾。

IDL语法

基本类型
  • bool (布尔值(true,false)
  • byte (8位有符号整型
  • i16 (16位有符号整型
  • i32 (32位有符号整型
  • i64 (64位有符号整型
  • double (64位浮点数
  • string (字符串,采用UTF-8编码
特殊类型
struct

struct格式定义如下:

struct <结构体名称> {
	<序号> : [字段性质]<字段类型><字段名称> [ = <默认值>] [; or , or ]
}

例如

//required表示该字段在传输过程一定要有,optional表示可以不传该字段,若不传该字段则也不会对该字段进行序列化。
struct User {
    1 : required string name;//该字段必须要有
    2 : optional i32 age = 0;//该字段可以没有,有默认值0
    3 : bool gender,//默认字段类型为optional,末尾可以以逗号结尾,可以以分号结尾,也可以啥也没有
}

注意

  1. struct不能继承,但是允许嵌套,但不允许自己嵌套自己
  2. 成员都是有明确类型
  3. 成员被正整数编号,编好不能重复,为了在传输过程中编码使用
  4. optional不填充则不会序列化,required必须填充也必须序列化
枚举(enum)

Thrift不支持枚举类嵌套,枚举常量必须是32位的正整数。例如

enum HttpStatus {
    OK = 200;
   NOTFOUND = 404;
}
容器

IDL中的容器只有三种,分别是list(即C++ STL的vector,Java中的ArrayList),map(C++ STL中的map,Java中的HashMap),set(C++中的set, Java中的HashSet)。使用容器类型时必须指定范性,集合中的元素可以是除了service中的任何类型,包括exception。

Exception

异常在语法和功能上类似结构体,区别是异常使用关键字exception,而且异常是继承每种语言的异常基础类。例如

exception MyException {
    1 : i32 errorcode;
    2 : string meg;
}
service ExampleService {
    string GetName() throw (1 : MyService e)
}
Service

服务的定义方法等同于面向对象的接口,例如

service HelloService {
    i32 sayInt(1 :  i32 param);
    string sayString(1 : string param);
    bool sayBool(1 : bool param);
}

命名空间(namespace)

Thrift的命名空间类似于C++中的namespace和Java中的package,他们提供了一个组织(隔离)代码的简便方式,命名空间也可以解决类型定义中的命名冲突。

namespace java com.example.test //生成Java代码
namespace cpp com.example.test //生成cpp代码

编译

编译器安装

参考官方文档

编译命令

# 生成Java代码
thrift -gen java user.thrift
# 生成C++代码
thrift -gen cpp user.thrift

生成其他语言的命令可以自行去如前所述apache官网查看~