一、引子
Thrift is an interface definition language and binary communication protocol that is used to define and create services for numerous languages.
Thrift是用于...(使用接口定义语言和二进制通信协议定义并创建跨语言服务) 的框架,允许开发者在不同的编程语言之间通信。
二、安装(OS: ubuntu18.04/ubuntu20.04/ubuntu22.04; Thrift: 0.20.0)
0. 更新包管理器
sudo apt update
1. 安装依赖
sudo apt install -y build-essential automake bison flex pkg-config libboost-all-dev linssl-dev
1) bison: Bison(GNU Bison)是一个用于生成解析器的工具。
2) flex:Flex(Fast Lexical Analyzer Generator)是一个用于生成词法分析器的工具。
3) libboost-all-dev:是 Boost C++ 库的开发包,包含了 Boost 库的所有开发文件和头文件。
4) libssl-dev:是 OpenSSL 库的开发包,它包含了 OpenSSL 库的头文件和用于开发的其他文件。
其余依赖较为常见。
2. 获取下载源码
wget http://apache.mirror.gtcomm.net/thrift/0.15.0/thrift-0.15.0.tar.gz
3. 解压缩文件
tar -xvzf thrift-0.15.0.tar.gz
4. 进入目录,配置并构建
cd thrift-0.20.0
./configure
make
5. 安装Thrift
sudo make install
三、案例
1. 开发流程
1)按照需求编写thrift接口定义文件
2)利用thrift binary为不同的语言生成代码
3)根据需求,修改生成的代码(Server端代码),以编写实际的业务逻辑
4)编写客户端代码,编译,集成。
2. rpc
1)创建目录并创建ping.thrift
mkdir thrift_ping cd thrift_ping touch ping.thrift
2)编写ping.thrift,其内容如下所示:
# ping.thrift /** * Thrift files can namespace, package, or prefix their output in various * target languages */ namespace cpp pingtest /** * Defining a class named pinger */ service pinger { /** * client calls ping method to make sure service process is active or dead */ void ping() }
3)生成服务器端模板代码
thrift --gen cpp -o . ping.thrift
主要服务器端的模板代码并不涉及业务,因此需要自己按需编写server端代码(仅作演示可用gen-cpp/pinger_server.skeleton.cpp)。
4)编译server端可执行文件
cp gen-cpp/* . g++ -g -Wall -std=c++11 -I/usr/local/include -L/usr/local/lib ./*.cpp -o server -lthrift
5)编写客户端 client.cpp ,其内容如下所示:
#include <iostream> #include <thrift/protocol/TBinaryProtocol.h> #include <thrift/transport/TSocket.h> #include <thrift/transport/TTransportUtils.h> #include "pinger.h" using namespace apache::thrift; using namespace apache::thrift::protocol; using namespace apache::thrift::transport; using namespace pingtest; int main() { std::shared_ptr<TTransport> socket(new TSocket("localhost", 9090)); std::shared_ptr<TTransport> transport(new TBufferedTransport(socket)); std::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport)); pingerClient client(protocol); try { transport->open(); client.ping(); transport->close(); } catch (TException& tx) { std::cout << "ERROR: " << tx.what() << std::endl; } return 0; }
6)编译客户端代码
g++ -g -Wall -std=c++11 client.cpp pinger.cpp -o client -lthrift
7)打开两个终端界面
1--运行服务器端,打开监听端口
./server
2--运行客户端,每运行一次,服务器端打印一遍"ping"
./client
**可自行尝试在两台服务器上运行上述代码,主要修改服务器端口中TSocket的地址信息为服务器的地址信息(IP地址),前提:两台设备可以相互ping通。**
3. 数据传输--与rpc差不多,不过有传递数据而已。
可参考以下博客(抱歉这里的拿来主义,偷点懒,若遇到环境问题,可留言)
技术: Thrift | 梅林日志 (wizardmerlin.github.io)
四、架构
从下往上依次是(有不同意见可指出来,十分欢迎):
1. 传输层
实际的数据传输发生在传输层。Thrift 提供了多种传输层协议,例如 TSocket、TFramedTransport、TBufferedTransport 等,用于在客户端和服务端之间传输数据。
2. 协议层
协议层定义了数据的序列化和反序列化规则,使得不同语言和平台之间可以有效地交换数据。Thrift 支持多种协议,包括 TBinaryProtocol、TJSONProtocol、TCompactProtocol 等。
3. 数据结构层
结构体、异常和集合:在Thrift中,可以定义结构体、集合和异常等数据结构。这些数据结构用于在服务器之间传输数据,且支持嵌套结构。
4. 服务层
Thrift服务:定义了在客户端和服务器之间远程调用的服务接口。通过 IDL 文件定义的服务接口在编译过程中生成对应的客户端和服务器代码,使得不同语言的应用能够通过这些服务进行通信。
5. 编译器层
Thrift编译器:IDL文件需要经过Thrift层处理。Thrift编译器将IDL文件转换为不同编程语言的代码,生成用于序列化和反序列化数据以及调用远程服务的代码。
6. IDL(Interface Definition Layer)层
IDL文件:首先定义了接口层的规范,这是通过使用IDL文件完成的。IDL文件描述了要在不同语言之间传输的数据结构和服务接口。
五、详细说明
1. Thrift支持的数据结构
1)基本数据类型
-
- bool: 布尔类型,取值为
true
或false
。 - byte: 8 位带符号整数。
- i16: 16 位带符号整数。
- i32: 32 位带符号整数。
- i64: 64 位带符号整数。
- double: 双精度浮点数。
- string: 字符串。
- bool: 布尔类型,取值为
2)结构体:结构体是一种用户定义的数据结构,可以包含多个字段。每个字段都有自己的类型和名称。
struct Person { 1: i32 id, 2: string name, 3: bool isStudent }
3)异常:异常是一种特殊的结构体,用于表示错误或异常情况。它们通常用于在服务调用过程中传递错误信息。
exception MyException { 1: i32 errorCode, 2: string errorMessage }
4)集合:支持列表、集合和映射等集合类型。
list<i32> intList; set<string> stringSet; map<string, double> stringToDoubleMap;
5)枚举:枚举是一种有限的、命名的整数类型,表示一组相关的常量。
enum Color { RED = 1, GREEN = 2, BLUE = 3 }
6)服务接口:服务接口定义了一组相关的远程过程调用(RPC)方法,客户端可以调用这些方法来与服务端进行通信。
service MyService { i32 add(1: i32 a, 2: i32 b), string concatenate(1: string str1, 2: string str2) }
2. Thrift支持的协议
1)TBinaryProtocol:二进制协议,使用二进制格式对数据进行序列化。这是 Thrift 默认的协议,提供了高效的序列化和压缩。
2)TCompactProtocol:紧凑协议,使用变长编码对数据进行序列化,以减小数据包的大小。适用于带宽受限的网络环境。
3)TJSONProtocol:JSON 协议,将数据序列化为 JSON 格式。适用于调试和与其他应用程序集成,但相对于二进制协议而言,JSON 格式会更大、更慢。
4)TSimpleJSONProtocol:简单的 JSON 协议,与 TJSONProtocol 类似,但生成的 JSON 格式更为简单,适用于人类可读的场景。
5)TDebugProtocol:调试协议,生成可读的文本输出,适用于调试目的。
3. Thrift支持的传输层
1)TSocket:使用传统的 TCP Socket 进行通信。通常用于在同一台机器上的进程之间或在网络上进行传输。
transport = TSocket(host, port)
2)TFramedTransport:在数据传输之前,在每个消息的开头添加消息的长度信息。这样可以确保接收方能够正确地解析每个消息。
transport = TFramedTransport(TSocket(host, port))
3)TBufferedTransport:缓冲传输,提供了一个缓冲区,可以在数据传输之前缓冲一定量的数据,以减少网络交互的次数。
transport = TBufferedTransport(TSocket(host, port))
4)TZlibTransport:使用 zlib 压缩数据,可以减小数据传输的大小,适用于带宽受限的网络环境。
transport = TZlibTransport(TSocket(host, port))
5)TMemoryBuffer:在内存中缓存数据,用于本地进程之间的通信,或者在需要对数据进行多次操作时。
transport = TMemoryBuffer()
6)TFileTransport:文件传输,用于通过文件进行数据传输。适用于大量数据的离线传输场景。
transport = TFileTransport(file)
7)TFastFramedTransport:类似于 TFramedTransport
,但使用了更加紧凑的帧格式,适用于带宽敏感的场景。
transport = TFastFramedTransport(TSocket(host, port))
六、源码分析
以后吧.......
七、参考博客
1. Archives | 梅林日志 (wizardmerlin.github.io)
2. Apache Thrift系列详解(一) - 概述与入门 - 知乎 (zhihu.com)
3. Thrift - 维基百科,自由的百科全书 (wikipedia.org)
标签:TSocket,ping,C++,cpp,Thrift,transport,thrift From: https://www.cnblogs.com/hjxiamen/p/17932740.html