概述
Apache Thrift是一种支持支持可伸缩、跨语言服务开发的软件框架,它结合一个软件栈和一个代码生成引擎来构建服务,这些服务在c++、Java、Python、PHP、Ruby、Erlang、Perl、Haskell、c#、Cocoa、JavaScript、Nodejs、Smalltalk、OCaml和Delphi以及其他语言之间高效无缝地工作。和protobuf类似,他也有自己的定义文件—— IDL (Interface Description Language),通过代码生成器来构建不同语言的客户端和服务端,从而实现跨平台、跨语言的数据传递(socket),是典型的 CS 结构。
基本数据类型
Thrift不支持无符号类型,因为Java不支持无符号类型。
RPC框架支持的数据类型取决于其支持的各个语言数据类型的交际。
- bool:布尔值(true or false)
- byte:8位有符号整数
- i16:16位有符号整数
- i32:32位有符号整数
- i64:64位有符号整数
- double:64位浮点数
- string:使用UTF-8编码编码的文本字符串
容器类型
容器集合中的元素可以是除了service之外的任何类型,包括exception。同时是可以使用 <T> 泛型的
- list: 有序的元素集合. 类似于STL vector, Java ArrayList, 脚本语言的原生array等。
- set: 无序的元素集合. 类似于STL set, Java HashSet, set in Python等. 注意: 由于PHP不支持set类型,Thrift的set在PHP中类似于 list。
- map: 键值对类型. 类似于 STL map, Java HashMap, PHP associative array, Python/Ruby dictionary等. While defaults are provided, the type mappings are not explicitly fixed(不知道这段话怎么理解,吐了). 添加了自定义代码生成器指令,以允许在各种目标语言中替换自定义类型。.
结构体——struct
类似于Protocol buffers中的message,具体详情之后再补充。
struct Work {
1: i32 num1 = 0,
2: i32 num2,
3: Operation op,
4: optional string comment,
}
异常——exception
Thrift支持自定义异常,和struct定义类似,只不过关键字是exception。
exception InvalidOperation {
1: i32 whatOp,
2: string why
}
支持枚举
enum Operation {
ADD = 1,
SUBTRACT = 2,
MULTIPLY = 3,
DIVIDE = 4
}
定义服务——service
service的定义在语义上等同于在面向对象编程中定义一个接口(或一个纯虚拟抽象类),Thrift编译器生成实现接口功能完备的客户端和服务器使用。
service由一组命名函数组成,每个函数都有一个参数列表和一个返回类型。
/**
* Ahh, now onto the cool part, defining a service. Services just need a name
* and can optionally inherit from another service using the extends keyword.
*/
service Calculator extends shared.SharedService {
/**
* A method definition looks like C code. It has a return type, arguments,
* and optionally a list of exceptions that it may throw. Note that argument
* lists and exception lists are specified using the exact same syntax as
* field lists in struct or exception definitions.
*/
void ping(),
i32 add(1:i32 num1, 2:i32 num2),
i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch),
/**
* This method has a oneway modifier. That means the client only makes
* a request and does not listen for any response at all. Oneway methods
* must be void.
*/
oneway void zip()
}
需要注意的是,除了Thrift定义的其他类型之外 void 是一个有效的返回类型。除此之外,an oneway modifier keyword may be added to a void function, which will generate code that does not wait for a response(我实在不知道怎么理解,官网这句话好像还挺重要的,以后理解了再回过头看吧,理解什么意思的人也可以留言告诉我QAQ)。请注意,一个单一的void函数将返回一个响应给客户端,以保证操作已经在服务器端完成。
通过单向方法调用,客户端只能保证请求在传输层成功。同一客户端的单向方法调用可能被服务器以并行/无序的方式执行。(With oneway method calls the client will only be guaranteed that the request succeeded at the transport layer. Oneway method calls of the same client may be executed in parallel/out of order by the server.)我尽力理解了,为了不误导大家,还是贴一下原文。
常量——const
/**
* Thrift also lets you define constants for use across languages. Complex
* types and structs are specified using JSON notation.
*/
const i32 INT32CONSTANT = 9853
const map<string,string> MAPCONSTANT = {'hello':'world', 'goodnight':'moon'}
namespace
Thrift 的命名空间相当于Java中的package,主要作用也是组织代码
namespace java tutorial
定义格式:namespace [语言名称] [路径]
文件引用——include
/**
* Thrift files can reference other Thrift files to include common struct
* and service definitions. These are found using the current path, or by
* searching relative to any paths specified with the -I compiler flag.
*
* Included objects are accessed using the name of the .thrift file as a
* prefix. i.e. shared.SharedObject
*/
include "shared.thrift"
可以通过 include 引用其他 .thrift 文件,可以在当前定义文件中把 [引用文件] 的定义包含过来。
字段修饰
同样可以定义 required / optional(必传/可不传),同样需要对字段进行标识,如下面定义中的1: 2: 3:
struct Work {
1: required i32 num1 = 0,
2: optional i32 num2,
3: optional string comment,
}