• Thrift入门初探(2)--thrift基础知识详解


      昨天总结了thrift的安装和入门实例,Thrift入门初探--thrift安装及java入门实例,今天开始总结一下thrift的相关基础知识.

      Thrift使用一种中间语言IDL,来进行接口的定义,下面来具体讲一下IDL可定义的几种常用数据类型和关键字.

    常用数据类型及关键字

      基本类型

        thrift不支持无符号的类型,无符号类型可以简单理解为不能表示负数,只能表示正数的类型,像java的基本数据类型都是有符号的类型.

    • byte:有符号字节
    • i32:32位有符号整数,此外还有i16,i64
    • double:64位浮点数
    • string:二进制字符串
    • bool 布尔值 true或false

      结构体类型(struct):

        类似于c语言的结构体定义,在java中会被转化为javabean类

    struct User {
      1: i32 id;
      2: string name;
      3: double salary;
      4: bool hasCar;
    }

      服务类型(service):

        service:对应服务的接口,内部可定义各种方法,相当于java中创建interface一样,创建的service经过代码生成命令会生成客户端,服务端的框架代码

    service Hello{
      string helloString(1:string s);
      i32 helloInt(1:i32 i);
      bool helloBoolean(1:bool b);
      void helloVoid();
      string helloNull();
    }

      异常类型(Exception):

    exception RequestException {

      1:i32 code;

      2:string detail;

    }

      容器类型

        集合中的元素可以是除了service之外的任意类型

       list<T>:有序列表,元素可重复

       set<T>:无需集合,元素不可重复

       map<K,V>:键值对集合

      枚举类型

      enum Color{

        RED,

        BLUE

      }

      命名空间(namespace)

        可以理解成java中的packet,用于避免一些代码冲突,每种语言都有属于自己的命名空间的方式,比如java语言,就可以使用java语言的格式

    namespace java com.wang.project

       此外还有一些语言特性和关键字就不一一介绍了,比如可选参数和必选参数,required和optional,定义常量const,引入文件include等

    Thrift支持的传输协议

      Thrift支持多种传输协议,我们可以根据自己的需要来选择合适的类型,总体上来说,分为文本传输和二进制传输,由于二进制传输在传输速率和节省带宽上有优势,所以大部分情况下使用二进制传输是比较好的选择.

    • TBinaryProtocol:使用二进制编码格式传输,是thrift的默认传输协议
    • TCompactProtocol:使用压缩格式传输
    • TJSONProtocol :使用JSON格式传输
    • TDebugProtocol – 使用易懂可读的文本格式进行传输,以便于debug
    • TSimpleJSONProtocol – 提供JSON只写的协议,适用于通过脚本语言解析

    Thrift支持的传输模式

      Thrift封装了一层传输层来支持底层的网络通信,在Thrift中称为Transport,不仅提供open,close,flush等方法,还有一些read/write方法.

    •   TSocket:阻塞式IO的Transport实现,用在客户端.
    •   TServerSocket:非阻塞式Socket,用于服务器端,用于监听TSocket.
    •   TNonblockingSocket:非阻塞式IO的实现
    •   TMemoryInputTransport: 封装了一个字节数组byte[]来做输入流的封装
    •   TFramedTransport- 同样使用非阻塞方式,按块的大小进行传输,输入流封装了TMemoryInputTransport  

    Thrift支持的服务模型

      TSimpleServer:

        这种工作模式只有一个线程,循环监听传过来的请求并对其进行处理,处理完才能接受下一个请求,是一种阻塞式IO的实现,因为效率比较低,实际线上环境一般用不到.一般用于开发时候演示工作流程时使用.  

      TNonblockingServer:

        这种模式与TsimpleServer最大的区别就是使用NIO,也就是非阻塞是IO的方式实现IO的多路复用,它可以同时监听多个socket的变化,但因为业务处理上还是单线程模式,所以在一些业务处理比较复杂耗时的时候效率还是不高,因为多个请求任务依然需要排队一个一个进行处理.

      TThreadPoolServer:

        这种模式引入了线程池,主线程只负责accept,即监听Socket,当有新的请求(客户端Socket)来时,就会在线程池里起一个线程来处理业务逻辑,这样在并发量比较大的时候(但不超过线程池的数量)每个请求都能及时被处理,效率比较高,但一旦并发量很大的时候(超过线程池数量),后面来的请求也只能排队等待.

      TThreadedSelectorServer:

        这是一种多线程半同步半异步的服务模型,是Thrift提供的最复杂最高级的服务模型,内部有一个专门负责处理监听Socket的线程,有多个专门处理业务中网络IO的线程,有一个专门负责决定将新Socket连接分配给哪一个线程处理的起负载均衡作用的线程,还有一个工作线程池.这种模型既可以响应大量并发连接的请求又可以快速对wangluoIO进行读写,能适配很多场景,因此是一种使用比较高频的服务模型.

    Thrift服务层编码

    try {
                System.out.println("服务端开启....");
                //1.创建TProcessor
                TProcessor tprocessor = new Hello.Processor<Hello.Iface>(new HelloServiceImpl());
                // 2.创建TserverTransport
                TServerSocket serverTransport = new TServerSocket(9898);
                //3.创建TProtocol
                TBinaryProtocol.Factory factory = new TBinaryProtocol.Factory();
    
                TServer.Args tArgs = new TServer.Args(serverTransport);
                tArgs.processor(tprocessor);
                tArgs.protocolFactory(factory);
                //4.创建Tserver,传入需要的参数,server将以上内容集成在一起
                TServer server = new TSimpleServer(tArgs);
                //5.启动server
                server.serve();
                }catch (TTransportException e) {
                e.printStackTrace();
            }

    根据代码可以看出服务端编码基本流程:

      0.实现服务处理接口impl,重写接口方法.

      1.创建TProcessor

      Processor封装了从输入数据流中读数据和向数据流中写数据的操作,与服务相关的Processor是由编译器编译IDL文件产生的,它的主要工作是:从连接中读取数据,把处理交给用户实现impl,最后把结果写到连接上.

      2.创建serverTransport

      TServerSocket是ServerTransport的阻塞式IO的实现.它实现了监听端口的作用,accept到的Socket类型都是客户端的TSocket类型(阻塞式Socket).

      3.创建TProtocol

      TProtocol定义了基本的协议信息,包括传输什么数据,如何解析传输的数据.   

      4.创建server

      根据需要选择使用不同的服务模式,代码中为了演示只是用了最简单TSimpleServer

      5.启动服务

    Thrift客户端编码

    System.out.println("客户端启动....");
            TTransport transport = null;
            try {
                //1.创建TTransport
                transport = new TSocket("localhost", 9898, 30000);
                // 2.创建TProtocol  协议要和服务端一致
                TProtocol protocol = new TBinaryProtocol(transport);
                //3.创建Client 打开transport
                Hello.Client client = new Hello.Client(protocol);
                transport.open();
                //4.调用Client响应方法
                String result = client.helloString("哈哈");
                System.out.println("Thrify client result =: " + result);
            } catch (TTransportException e) {
                e.printStackTrace();
            } catch (TException e) {
                e.printStackTrace();
            } finally {
                if (null != transport) {
                    transport.close();
                }
            }

       新手入门,根据自己的理解以及拜阅了网友们的文章总结的难免有不当之处的,轻喷.

    相关博文

    Thrift入门初探--thrift安装及java入门实例

      参考资料

    Thrift源码分析(六)-- Transport传输层分析

    和 Thrift 的一场美丽邂逅

    thrift入门教程

  • 相关阅读:
    小程序云函数 Error: errCode: -404011 cloud function execution error
    Fiddler+雷电模拟器进行APP抓包
    Vue优化常用技巧
    sftp常用命令整理
    React生命周期学习整理
    git 提交跳过检查
    漂亮的代码系列
    关于我系列
    架构系列
    深度学习系列
  • 原文地址:https://www.cnblogs.com/fingerboy/p/6427753.html
Copyright © 2020-2023  润新知