- 前言
- 特点
- 高效性的体现
- 可拓展性的体现
- 应用场景
- 示例
- 拓展
- 其他常用协议
- 接口描述语言(IDL)
- TBinaryProtocol
- TCompactProtocol
- TDebugProtocol
- TDenseProtocol
- TJSONProtocol
前言
Thrift协议是一种接口描述语言和二进制通讯协议,它被用来定义和创建跨语言的服务。它被当作一个远程过程调用(RPC)框架来使用,是由Facebook为“大规模跨语言服务开发”而开发的。
Thrift通过一个代码生成引擎联合了一个软件栈,来创建不同程度的、无缝的跨平台高效服务,可以使用C#、C++(基于POSIX兼容系统)、Cappuccino、Cocoa、Delphi、Erlang、Go、Haskell、Java、Node.js、OCaml、Perl、PHP、Python、Ruby和Smalltalk。虽然它以前是由Facebook开发的,但它现在是Apache软件基金会的开源项目了。
Thrift支持众多通讯协议:TBinaryProtocol(一种简单的二进制格式,简单,但没有为空间效率而优化),TCompactProtocol(更紧凑的二进制格式,处理起来通常同样高效),TDebugProtocol(一种人类可读的文本格式,用来协助调试),TDenseProtocol(与TCompactProtocol类似,将传输数据的元信息剥离),TJSONProtocol(使用JSON对数据编码)。
相比于传统的HTTP协议,Thrift效率更高,传输占用带宽更小。另外,Thrift是跨语言的。它的接口描述文件,通过其编译器可以生成不同开发语言的通讯框架。有了Thrift,就可以定义一个服务或改变通讯和传输协议,而无需重新编译代码。
Thrift还包含了服务器基础设施来集成协议和传输,如阻塞、非阻塞及多线程服务器。栈中作为I/O基础的部分对于不同的语言则有不同的实现。
特点
Thrift协议主要有以下特点:
- 跨语言特性:支持多种编程语言,包括Java、Python、C++、C#、Go等,可以实现不同语言之间的通信和数据交换。
- 高效性:采用二进制协议,相比于文本协议如XML或JSON,二进制协议具有更小的体积和更高的性能。
- 可扩展性:Thrift协议采用二进制编码方式,相比于传统的JSON和XML格式,传输效率更高、体积更小。同时,Thrift协议支持动态扩展,新的数据结构可以在不破坏原先系统的情况下进行增加或修改。
高效性的体现
- 二进制编码:Thrift采用二进制编码格式,相对于XML和JSON等文本格式,二进制格式具有更小的体积和更高的传输效率,可以显著降低数据传输的开销。
- 自动生成代码:Thrift编译器可以根据定义的接口自动生成不同语言的代码,这些代码可以高效地实现客户端和服务器端的通信,避免了手动编写通信代码的工作量和错误风险。
- 高效的序列化/反序列化:Thrift支持多种序列化协议,可以根据需要选择最适合的协议进行数据序列化和反序列化,以提高数据处理的效率。
- 并发处理:Thrift支持并发请求处理,可以高效地处理大量的并发请求,适用于大规模、高并发的分布式系统。
- 跨语言服务框架:通过定义IDL(接口定义语言)来描述服务接口,然后使用Thrift编译器生成不同语言的代码,可以快速实现跨语言的服务调用,提高系统的灵活性和可扩展性。
这些特点使得Thrift协议在处理大规模数据和提供高效通信方面具有显著优势,适用于需要高性能、高并发、跨语言通信的应用场景。
可拓展性的体现
Thrift中的可拓展性主要体现在以下几个方面:
- 接口定义的动态扩展:Thrift IDL (Interface Description Language) 允许我们在不必重启服务的情况下添加或移除数据类型和函数。这主要得益于Thrift的动态扩展特性,它允许新的数据结构在不破坏原有系统的情况下进行增加或修改。
- 跨语言服务开发:Thrift支持多种编程语言,包括Java、C++、Python、PHP等等,使得不同的语言可以方便地进行数据交互和通信。这种跨语言的能力使得Thrift在大型分布式系统的开发中表现出良好的拓展性。
- 插件机制:Thrift提供了插件机制,用户可以很方便地给Thrift添加功能,比如日志、监控、认证等。这种插件机制使得Thrift在保持核心功能的同时,能够灵活地适应不同的需求和环境。
- 容错和可靠性:Thrift提供了多种容错和重试机制,可以在网络不稳定或者服务不可用的情况下保证通信的可靠性。这种特性使得Thrift在复杂的网络环境中表现出良好的稳定性和可靠性。
Thrift的可拓展性体现在其动态扩展性、跨语言能力、插件机制以及容错和可靠性等多个方面,使得Thrift能够灵活地适应不同的需求和环境,从而在大型分布式系统的开发和维护中得到广泛应用。
应用场景
Thrift协议被广泛应用于各种不同的应用场景。以下是其中一些典型的应用场景:
- 大型数据交换及存储:Thrift适用于搭建大型数据交换及存储的通用工具,对于大型系统中的内部数据传输,无论在性能、传输大小上相对于JSON和xml都有明显的优势。
- 跨语言服务开发:Thrift可以用于在多种语言之间进行通信,例如在Evernote API平台开发的客户端与Evernote服务器之间的通信与数据传输。
- HBase等数据库服务:Thrift用于HBase中,提供跨平台的服务接口,客户端可以通过thrift的命令生成不同版本的客户端代码,根据定义的数据格式,对远程HBase服务端进行操作。
- 其他系统:如facebook的scribe系统、淘宝的timetunnel系统和Hive等等。
示例
当然,以下是另一个Java使用Thrift的代码示例,该示例演示了如何使用Thrift生成Java代码并实现简单的Hello World服务:
- 首先,我们需要定义一个Thrift接口文件,例如
HelloService.thrift
:
service HelloService {
string sayHello(1:string name)
}
- 然后,我们需要使用Thrift编译器生成Java代码。假设我们已经安装了Thrift,可以在命令行中输入以下命令:
thrift --gen java HelloService.thrift
这将在当前目录下生成gen-java
文件夹,其中包含生成的Java代码。
3. 接下来,我们可以实现Hello Service服务。在HelloService.java
文件中,我们需要实现sayHello
方法:
public class HelloService {
public static class Iface {
public String sayHello(String name) {
return "Hello, " + name + "!";
}
}
public static class Client extends HelloService.Iface {
private static final TSerializer serializer = new TBinaryProtocol.TBinaryProtocolAccelerated(new TTransport.SizeEstimatingTFramedTransportFactory().getTransport(new TSocket("localhost", 9090)));
private static final TDeserializer deserializer = new TBinaryProtocol.TBinaryProtocolAccelerated(new TTransport.SizeEstimatingTFramedTransportFactory());
private static final String ENDPOINT = "localhost:9090"; // 服务器地址和端口号
public Client() throws TException {
this(new TSocket(ENDPOINT));
}
public Client(String address) throws TException {
this(new TSocket(address));
}
public Client(TTransport transport) throws TException {
TProtocol protocol = new TBinaryProtocol(transport);
transport.open();
try {
sayHello(protocol, protocol);
} finally {
transport.close();
}
}
public void sayHello(TProtocol in, TProtocol out) throws TException {
out.writeString("sayHello"); // 写入方法名
out.writeString(name); // 写入参数名和参数值
out.flush(); // 刷新缓冲区,确保数据写入到传输层中
String response = in.readString(); // 从输入流中读取返回值
System.out.println(response); // 输出返回值到控制台中
}
}
public static void main(String[] args) throws Exception {
TServer server = new TSimpleServer(new Args(new HelloService.Processor<HelloService.Iface>(new HelloService.Client()))); // 创建服务器对象并启动服务器进程
}
}
拓展
其他常用协议
通过下面的链接,我们一起来来了解更多的常用的一些网络协议
HTTP/2.0协议详解
HTTP1.1协议详解
gRPC协议详解
QUIC协议详解
Dubbo协议详解
RMI协议详解
Hessian协议详解
HTTP1.0协议详解
接口描述语言(IDL)
接口描述语言(Interface Description Language,IDL)是一种用于描述软件系统中组件之间交互的语言。它通常用于定义软件系统中的接口,包括接口的名称、参数、返回值以及接口的行为等。
接口描述语言可以帮助开发人员定义系统中的服务,并描述服务之间的交互。通过使用IDL,开发人员可以更容易地理解系统的功能和结构,以及各个组件之间的关系。此外,IDL还可以用于生成相应的代码,以便在程序中实现这些接口。
常见的接口描述语言包括Java IDL(Java Interface Definition Language)、CORBA(Common Object Request Broker Architecture)IDL和Web Services Description Language(WSDL)等。这些语言都具有不同的语法和用途,但都用于描述软件系统中的接口和组件之间的交互。
TBinaryProtocol
TBinaryProtocol是Apache Thrift中使用的二进制协议,用于在各种语言之间进行高效的数据传输。它使用二进制格式进行数据编码,相对于文本协议(如JSON或XML)具有更小的数据体积和更高的传输效率。
TBinaryProtocol是Thrift默认的传输协议,它以二进制格式对数据进行编码,使得数据在传输过程中更加紧凑和高效。这种协议在网络传输中能够提供更快的速度和更低的网络开销。
TBinaryProtocol可以用于各种不同的编程语言,包括Java、C++、Python、PHP等等。它支持跨语言服务开发,使得不同的语言可以方便地进行数据交互和通信。
总的来说,TBinaryProtocol是一种非常高效的二进制协议,适用于需要高性能、高并发、跨语言通信的应用场景。
TCompactProtocol
TCompactProtocol是Apache Thrift中的一种高效密集型的二进制序列化协议。它使用Variable-Length Quantity (VLQ) 编码对数据进行压缩,以更小的数据体积和更高的传输效率实现数据传输。
相对于其他协议,TCompactProtocol具有更高的性能和更低的网络开销。它适用于在网络传输中需要处理大量数据的应用场景,如大数据处理、分布式计算等。
TCompactProtocol支持各种不同的编程语言,包括Java、C++、Python等等。它适用于跨语言服务开发,使得不同的语言可以方便地进行数据交互和通信。
TDebugProtocol
TDebugProtocol是Apache Thrift中的一种调试协议。它通常用于在开发阶段对Thrift应用程序进行调试和测试。
TDebugProtocol以文本形式展现数据,方便阅读和理解。它可以将数据按照一定的格式输出,使得开发人员能够更方便地对数据进行检查和分析。
虽然TDebugProtocol在性能上不如二进制协议(如TBinaryProtocol和TCompactProtocol),但在开发和测试阶段,它可以帮助开发人员更好地发现和解决潜在的问题,提高应用程序的可靠性和稳定性。
总的来说,TDebugProtocol是一种用于调试和测试Thrift应用程序的协议,适用于开发阶段。
TDenseProtocol
TDenseProtocol是Apache Thrift中的一种密集型协议。它的主要特点是尽可能使用小的空间,通过减少元数据的传输来提高数据传输速度。
TDenseProtocol有两种类型的实例对象,一种是独立的,用于编码和解码;另一种是非独立的实例类型,可以用于rpc通信。这种协议相比TBinaryProtocol和TCompactProtocol,减少了部分元数据的传输,例如struct结构里面的字段id和数据类型,从而极大地减少了流量,提高了速度。
虽然TDenseProtocol有减少元数据传输的优势,但也存在一些缺陷,例如抽象效果会降低,需要维持第二个代码生成器,以及与旧版本的兼容性可能会很困难。因此,选择这个协议作为传输层之上的协议类型需要经过比较慎重的考虑。
总的来说,TDenseProtocol是一种用于提高数据传输速度和减少流量的密集型协议,适用于特定的应用场景。
TJSONProtocol
TJSONProtocol是Apache Thrift中的一种JSON序列化协议。它使用JSON格式对数据进行编码,使得数据在传输过程中能够以结构化、可读性更好的方式进行传输。
TJSONProtocol将Thrift中的数据类型转换为JSON格式的字符串,以便在不同的语言和平台之间进行数据交换。它支持各种不同的编程语言,包括Java、C++、Python等等。
虽然TJSONProtocol在性能上可能不如二进制协议(如TBinaryProtocol和TCompactProtocol),但它在数据可读性和结构化方面具有优势,适用于需要跨语言通信和数据交换的场景。
总的来说,TJSONProtocol是一种用于将Thrift数据类型转换为JSON格式的序列化协议,适用于需要跨语言通信和数据交换的应用场景。