• Thrift协议详解


    在这里插入图片描述
    在这里插入图片描述

    前言

    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协议主要有以下特点:

    1. 跨语言特性:支持多种编程语言,包括Java、Python、C++、C#、Go等,可以实现不同语言之间的通信和数据交换。
    2. 高效性:采用二进制协议,相比于文本协议如XML或JSON,二进制协议具有更小的体积和更高的性能。
    3. 可扩展性:Thrift协议采用二进制编码方式,相比于传统的JSON和XML格式,传输效率更高、体积更小。同时,Thrift协议支持动态扩展,新的数据结构可以在不破坏原先系统的情况下进行增加或修改。

    高效性的体现

    1. 二进制编码:Thrift采用二进制编码格式,相对于XML和JSON等文本格式,二进制格式具有更小的体积和更高的传输效率,可以显著降低数据传输的开销。
    2. 自动生成代码:Thrift编译器可以根据定义的接口自动生成不同语言的代码,这些代码可以高效地实现客户端和服务器端的通信,避免了手动编写通信代码的工作量和错误风险。
    3. 高效的序列化/反序列化:Thrift支持多种序列化协议,可以根据需要选择最适合的协议进行数据序列化和反序列化,以提高数据处理的效率。
    4. 并发处理:Thrift支持并发请求处理,可以高效地处理大量的并发请求,适用于大规模、高并发的分布式系统。
    5. 跨语言服务框架:通过定义IDL(接口定义语言)来描述服务接口,然后使用Thrift编译器生成不同语言的代码,可以快速实现跨语言的服务调用,提高系统的灵活性和可扩展性。

    这些特点使得Thrift协议在处理大规模数据和提供高效通信方面具有显著优势,适用于需要高性能、高并发、跨语言通信的应用场景。

    可拓展性的体现

    Thrift中的可拓展性主要体现在以下几个方面:

    • 接口定义的动态扩展:Thrift IDL (Interface Description Language) 允许我们在不必重启服务的情况下添加或移除数据类型和函数。这主要得益于Thrift的动态扩展特性,它允许新的数据结构在不破坏原有系统的情况下进行增加或修改。
    • 跨语言服务开发:Thrift支持多种编程语言,包括Java、C++、Python、PHP等等,使得不同的语言可以方便地进行数据交互和通信。这种跨语言的能力使得Thrift在大型分布式系统的开发中表现出良好的拓展性。
    • 插件机制:Thrift提供了插件机制,用户可以很方便地给Thrift添加功能,比如日志、监控、认证等。这种插件机制使得Thrift在保持核心功能的同时,能够灵活地适应不同的需求和环境。
    • 容错和可靠性:Thrift提供了多种容错和重试机制,可以在网络不稳定或者服务不可用的情况下保证通信的可靠性。这种特性使得Thrift在复杂的网络环境中表现出良好的稳定性和可靠性。

    Thrift的可拓展性体现在其动态扩展性、跨语言能力、插件机制以及容错和可靠性等多个方面,使得Thrift能够灵活地适应不同的需求和环境,从而在大型分布式系统的开发和维护中得到广泛应用。

    在这里插入图片描述

    应用场景

    Thrift协议被广泛应用于各种不同的应用场景。以下是其中一些典型的应用场景:

    1. 大型数据交换及存储:Thrift适用于搭建大型数据交换及存储的通用工具,对于大型系统中的内部数据传输,无论在性能、传输大小上相对于JSON和xml都有明显的优势。
    2. 跨语言服务开发:Thrift可以用于在多种语言之间进行通信,例如在Evernote API平台开发的客户端与Evernote服务器之间的通信与数据传输。
    3. HBase等数据库服务:Thrift用于HBase中,提供跨平台的服务接口,客户端可以通过thrift的命令生成不同版本的客户端代码,根据定义的数据格式,对远程HBase服务端进行操作。
    4. 其他系统:如facebook的scribe系统、淘宝的timetunnel系统和Hive等等。

    在这里插入图片描述

    示例

    当然,以下是另一个Java使用Thrift的代码示例,该示例演示了如何使用Thrift生成Java代码并实现简单的Hello World服务:

    1. 首先,我们需要定义一个Thrift接口文件,例如HelloService.thrift
    service HelloService {
      string sayHello(1:string name)
    }
    
    • 1
    • 2
    • 3
    1. 然后,我们需要使用Thrift编译器生成Java代码。假设我们已经安装了Thrift,可以在命令行中输入以下命令:
    thrift --gen java HelloService.thrift
    
    • 1

    这将在当前目录下生成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()))); // 创建服务器对象并启动服务器进程
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    在这里插入图片描述

    拓展

    其他常用协议

    通过下面的链接,我们一起来来了解更多的常用的一些网络协议

    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格式的序列化协议,适用于需要跨语言通信和数据交换的应用场景。

    在这里插入图片描述

  • 相关阅读:
    如何查看BWP相关log
    拥抱AI,怎么跨越Prompt这道鸿沟?
    PostgreSQL docker compose安装配置
    cos和obs腾讯云,和华为云的区别
    linux安装Yum
    BufferPool之链表
    java毕业设计企业产品在线展示销售平台源码+lw文档+mybatis+系统+mysql数据库+调试
    人脸识别-Loss-2017:SphereFace【基于angular margin这一流派的人脸识别本质上来说就是基于margin的分类】
    鸿蒙轻内核M核源码分析系列七 动态内存Dynamic Memory
    web期末作业设计网页 HTML+CSS+JavaScript仿王者荣耀游戏新闻咨询(网页设计期末课程设计)
  • 原文地址:https://blog.csdn.net/zhangzehai2234/article/details/134483983