枫叶居

桃李春风一杯酒,江湖夜雨十年灯

0%

Thrift教程

1.Thrift简介

转载说明:本文章为作者原创,转载请标注原文地址

Thrift由Facebook开发,解决了由不同语言编写的服务之间的调用问题。2009年Facebook将Thrift贡献给Apache基金会,成为一个开源项目。Thrift为典型的C/S架构,采用IDL(Interface Description Language),定义接口。

Thrift提供了命令行工具thrift,根据指定的IDL定义文件,生成不同语言的代码。因Thrift的依赖比较多,所以建议读者,采用自己开发平台的包管理工具进行安装。本人平时在macOS下进行开发工作,采用brew install thrift,便可自动完成了thrift的安装。

2.Thrift IDL介绍

Thrift IDL的语法比较接近C++,熟悉C++的读者,可以迅速掌握Thrift IDL的语法。由于IDL语法上比较接近C++,所以Thrift IDL比较偏向于静态语言,Python、Ruby等动态语言开发者在使用IDL定义接口时需要特别注意。

Thrift IDL支持C/C++风格的“//”,“/*,*/”注释,也支持Python风格的”#”注释。

1.基本数据类型

  • bool: A boolean value, true or false(注:布尔值)
  • byte: A signed byte(注:有符号字节
  • i16: A 16-bit signed integer(注:16位有符号数
  • i32: A 32-bit signed integer(注:32位有符号数
  • i64: A 64-bit signed integer(注:64位有符号数
  • double: A 64-bit floating point number(注:64位浮点数
  • string: An encoding-agnostic text or binary string(注:编码无关的字符串
  • void: Void (注:无返回值

2.复合类型

1.struct

struct——结构体类型,类似于C/C++中的结构体类型,将不同类型的数据聚合到一块儿。(注:描述面向对象语言中的类)。

1
2
3
4
5
6
7
8
struct User {
1: i32 id,
2: string user_name,
3: required bool is_admin,
4: optional string nick_name,
5: optional string sex = "male",
20: optional string city,
}

注意:

  1. optional关键字标识该字段为可选的。
  2. required关键字标识该字段为必填的。
  3. 定义中的序号,不可重复,但不是必须连续的。

2.enum

enum枚举类型

1
2
3
4
5
enum UserType {
BLOCKED = 0,
NORMAL = 1,
ADMIN = 2,
}

3.容器类型

容器类型比较类似于C++ STL中的容器类型,Thrift提供了三种容器类型:list,map,set。

  • list<T>: 由元素T组成的有序列表,Thrift将该容器类型编译为,C++ STL中的vector,Java中ArrayList,Python中list等等…
  • set<T>: 无序的集合,Thrift将该容器类型编译为,C++ STL中的set,Java中的HashSet,Python中set等等…
  • map<T1, T2>: k-v映射,Thrift将该容器类型编译为,C++ STL中的map,Java中的HashMap,Python中的dict等等…

4.自定义类型

Thrift支持C/C++风格的,typedef关键字,用于声明自定义类型。

1
typedef i32 Integer

5.异常

Thrift支持自定义异常,语法同struct类型的定义相似,如下所示:

1
2
3
exception NotFound {
1: string message,
}

注:在编写服务端代码时,仅仅在代码中抛出异常,是不够的,需要在定义接口时,指明该接口可能抛出的异常

6.服务

Thrift IDL中的Service,与Java中的Interface有异曲同工之妙。Thrift定义服务的语法如下:

1
2
3
4
5
service <name> {
<returntype> <name>(<arguments>)
[throws (<exceptions>)]
...
}

定义一个获取用户的Service示例如下:

1
2
3
4
5
service UserService {
User query_user(1: i32 user_id) throws (
1: NotFound not_found),
User add_user(1: User user);
}

注:service中接口定义之间的分割符号,可以是”,“,也可以是”;“。

7.命名空间

Thrift支持C++风格的命明空间,等同于Java、Python中的package的概念。Thrift定义命名空间的语法如下:

1
2
3
namespace cpp com.example.project
namespace java com.example.project
namespace py com.example.project

3.Thrift使用方法

示例文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// filename: user.thrift
namespace py thrift.rpc.user

enum Sex {
FEMALE = 0,
MALE = 1,
}

struct User {
1: string user_name,
2: Sex sex,
3: required i32 age,
4: optional string city,
}

exception NotFound {
1: string message,
}

service UserService {
User query_user(1: i32 id) throws (
1: NotFound not_found),
}

在Shell里面输入如下命令,生成Python代码:

1
thrift -out py --gen py:new_style,utf8strings,coding=utf-8

--gen参数,指定待目标语言,冒号后以都好分割的为thrift为该语言提供的选项。

-out参数,指定thrift生成代码的存放路径(**注:仅有一个-**)

更详细的用法,可通过thrift --help获取。

参考资料

[1]Thrift官方手册

[2]Thrift:The Missing Guide

[3]Thrift官方示例

坚持原创技术分享,您的支持将鼓励我继续创作!