Thrift概述
给chatgpt加了给示例的custom instructions,竟然这么详细。
Thrift(又称为Apache Thrift)是一种开源的跨语言服务开发框架,它由Apache软件基金会维护。Thrift旨在简化多语言之间的服务通信,并且使得跨平台的开发变得更加容易。
Thrift通过定义一个IDL(接口定义语言)文件来描述数据类型和服务接口,然后使用Thrift编译器生成各种编程语言的代码,这些代码包括了用于序列化和反序列化数据、网络通信和服务调用的功能。这种方式使得不同编程语言的应用能够无缝地进行通信和协作,因为它们共享了相同的数据结构和接口定义。
让我们来看一个简单的例子,假设你有一个服务需要在不同的编程语言之间通信,比如在Golang和Python之间。你可以使用Thrift定义数据结构和服务接口,然后编译生成对应的代码。以下是一个使用Thrift定义和使用服务的示例:
首先,在Thrift的IDL文件中定义数据结构和服务接口,比如 example.thrift:
namespace go example
struct Person {
1: required string name
2: required i32 age
}
service ExampleService {
void printPerson(1: Person person)
}
然后,使用Thrift编译器生成Golang和Python代码:
thrift --gen go example.thrift
thrift --gen py example.thrift
在生成的代码中,你可以在Golang中调用服务:
package main
import (
"fmt"
"git.apache.org/thrift.git/lib/go/thrift"
"example"
)
func main() {
transportFactory := thrift.NewTTransportFactory()
protocolFactory := thrift.NewTBinaryProtocolFactoryDefault()
transport, err := thrift.NewTSocket("localhost:9090")
if err != nil {
fmt.Println("Error opening socket:", err)
return
}
transport = transportFactory.GetTransport(transport)
defer transport.Close()
if err := transport.Open(); err != nil {
fmt.Println("Error opening transport:", err)
return
}
client := example.NewExampleServiceClientFactory(transport, protocolFactory)
person := example.NewPerson()
person.Name = "Alice"
person.Age = 30
err = client.PrintPerson(person)
if err != nil {
fmt.Println("Error calling service:", err)
return
}
}
同时,你也可以在Python中调用服务:
from example import ExampleService
from example.ttypes import Person
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
transport = TSocket.TSocket('localhost', 9090)
transport = TTransport.TBufferedTransport(transport)
protocol = TBinaryProtocol.TBinaryProtocol(transport)
client = ExampleService.Client(protocol)
transport.open()
person = Person()
person.name = "Bob"
person.age = 25
client.printPerson(person)
transport.close()
这就是Thrift的基本概述。通过Thrift,你可以方便地在不同的编程语言中定义和使用服务接口,实现跨语言的通信。
ThriftIDL
基本类型
thrift不支持无符号类型,因为很多编程语言不存在无符号类型,比如java
- byte: 有符号字节
- i16: 16位有符号整数
- i32: 32位有符号整数
- i64: 64位有符号整数
- double: 64位浮点数
- string: 字符串
容器类型
集合中的元素可以是除了service之外的任何类型,包括exception。
- list<\T>: 一系列由T类型的数据组成的有序列表,元素可以重复
- set<\T>: 一系列由T类型的数据组成的无序集合,元素不可重复
- map<K, V>: 一个字典结构,key为K类型,value为V类型
结构体(struct)
struct People {
1: string name;
2: i32 age;
3: string sex;
}
枚举(enum)
enum Sex {
MALE,
FEMALE
}
异常(exception)
thrift支持自定义exception,规则和struct一样,如下:
exception RequestException {
1: i32 code;
2: string reason;
}
服务(service)
service HelloWordService {
// service中定义的函数,相当于Java interface中定义的函数
string doAction(1: string name, 2: i32 age);
}
类型定义
typedef i32 Integer
typedef i64 Long
注意,末尾没有逗号或者分号
常量(const)
const i32 MAX_RETRIES_TIME = 10
const string MY_WEBSITE = "http://qifuguang.me";
末尾的分号是可选的,可有可无,并且支持16进制赋值
命名空间
namespace api
文件包含
include "global.thrift"
注释
thrift注释方式支持shell风格的注释,支持C/C++风格的注释,即#和//开头的语句都单当做注释,/**/包裹的语句也是注释。
可选与必选
thrift提供两个关键字required,optional,分别用于表示对应的字段时必填的还是可选的。例如:
struct People {
1: required string name;
2: optional i32 age;
}
表示name是必填的,age是可选的。