thrift

1.簡介

    常見的服務調用有基於soap的web service方式,也有基於restful方式的接口方式,數據傳輸格式有json和xml,xml方式傳輸數據效率相對較低,json方式體積小,相對不夠完善。Facebook 開發的遠程服務調用框架 Apache Thrift,它採用接口描述語言定義並建立服務,支持可擴展的跨語言服務開發,所包含的代碼生成引擎能夠在多種語言中,如 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk 等建立高效的、無縫的服務,其傳輸數據採用二進制格式,相對 XML 和 JSON 體積更小,對於高併發、大數據量和多語言的環境更有優點。--來自html

2.thrift原理

image.png

TTransport層:表明thrift的數據傳輸方式,thrift定義了以下幾種經常使用數據傳輸方式java

  • TSocket: 阻塞式socket;
  • TFramedTransport: 以frame爲單位進行傳輸,非阻塞式服務中使用;
  • TFileTransport: 以文件形式進行傳輸;

TProtocol層:表明thrift客戶端和服務端之間傳輸數據的協議,通俗來說就是客戶端和服務端之間傳輸數據的格式(例如json等),thrift定義了以下幾種常見的格式web

  • TBinaryProtocol: 二進制格式;
  • TCompactProtocol: 壓縮格式;
  • TJSONProtocol: JSON格式;
  • TSimpleJSONProtocol: 提供只寫的JSON協議;

thrift支持的Server模型apache

  • TSimpleServer: 簡單的單線程服務模型,經常使用於測試;
  • TThreadPoolServer: 多線程服務模型,使用標準的阻塞式IO;
  • TNonBlockingServer: 多線程服務模型,使用非阻塞式IO(須要使用TFramedTransport數據傳輸方式);
  • THsHaServer: THsHa引入了線程池去處理,其模型讀寫任務放到線程池去處理,Half-sync/Half-async處理模式,Half-async是在處理IO事件上(accept/read/write io),Half-sync用於handler對rpc的同步處理;

3.使用流程

  1. 在windows上下載編譯器

    下載地址json

  2. 編寫thrift idl文件windows

    文件名:GeneralInterface.thrift
    
    namespace java com.xiayu.thrift
    
    service GeneralThriftService{
        string generalService(1:string generalPar)
    }
  3. 生成java文件restful

    thrift-0.13.0.exe -r -gen java ./GeneralInterface.thrift
  4. 項目中加入thrift依賴(maven)多線程

    <dependency>
         <groupId>org.apache.thrift</groupId>
         <artifactId>libthrift</artifactId>
         <version>0.13.0</version>
     </dependency>
     <dependency>
         <groupId>org.slf4j</groupId>
         <artifactId>slf4j-log4j12</artifactId>
         <version>1.7.5</version>
     </dependency>
  5. 服務端併發

    package com.xiayu.thrift;
    
      import org.apache.thrift.TProcessor;
      import org.apache.thrift.protocol.TBinaryProtocol;
      import org.apache.thrift.protocol.TCompactProtocol;
      import org.apache.thrift.server.*;
      import org.apache.thrift.transport.*;
    
      public class ThriftServer {
    
          private static int port = 8089;
    
          public static void main(String[] args) {
              try {
      //              -----------單線程阻塞io類型-----------------------
      //            TProcessor processor = new GeneralThriftService.Processor<GeneralThriftService.Iface>(new ThriftGeneralService());
      //            TServerSocket serverTransport = new TServerSocket(port);
      //            TTransportFactory transportFactory = new TFramedTransport.Factory();
      //            TBinaryProtocol.Factory factory = new TBinaryProtocol.Factory();
      //            TServer.Args tArgs = new TServer.Args(serverTransport);
      //            tArgs.protocolFactory(factory);
      //            tArgs.transportFactory(transportFactory);
      //            tArgs.processor(processor);
      //            TServer server = new TSimpleServer(tArgs);
      //            server.serve();
      //            System.out.println("Thrift Server started");
      //            -------------------------------------
      //             使用非阻塞式IO,服務端和客戶端須要指定TFramedTransport數據傳輸的方式
      //            TProcessor processor = new GeneralThriftService.Processor<GeneralThriftService.Iface>(new ThriftGeneralService());
      //            TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(port);
      //            TNonblockingServer.Args tnbArgs = new TNonblockingServer.Args(tnbSocketTransport);
      //            tnbArgs.processor(processor);
      //            tnbArgs.transportFactory(new TFramedTransport.Factory());
      //            tnbArgs.protocolFactory(new TCompactProtocol.Factory());
      //            TServer server = new TNonblockingServer(tnbArgs);
      //            server.serve();
      //            -------------------------------------
      //          使用非阻塞式IO,服務端和客戶端須要指定TFramedTransport數據傳輸的方式
      //            TProcessor processor = new GeneralThriftService.Processor<GeneralThriftService.Iface>(new ThriftGeneralService());
      //            TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(port);
      //            TNonblockingServer.Args tnbArgs = new TNonblockingServer.Args(tnbSocketTransport);
      //            tnbArgs.processor(processor);
      //            tnbArgs.transportFactory(new TFramedTransport.Factory());
      //            tnbArgs.protocolFactory(new TCompactProtocol.Factory());
      //            TServer server = new TNonblockingServer(tnbArgs);
      //            server.serve();
      //          使用非阻塞式IO,服務端和客戶端須要指定TFramedTransport數據傳輸的方式
                  TProcessor processor = new GeneralThriftService.Processor<GeneralThriftService.Iface>(new ThriftGeneralService());
                  TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(port);
                  TNonblockingServer.Args tnbArgs = new TNonblockingServer.Args(tnbSocketTransport);
                  tnbArgs.processor(processor);
                  tnbArgs.transportFactory(new TFramedTransport.Factory());
                  tnbArgs.protocolFactory(new TCompactProtocol.Factory());
                  TServer server = new TNonblockingServer(tnbArgs);
                  server.serve();
              } catch (TTransportException e) {
                  System.out.println("Starting Thrift Server......Error!!!");
                  e.printStackTrace();
              }
          }
      }
  6. 客戶端框架

    package com.xiayu.thrift;
    
      import org.apache.thrift.TException;
      import org.apache.thrift.protocol.TBinaryProtocol;
      import org.apache.thrift.protocol.TCompactProtocol;
      import org.apache.thrift.protocol.TProtocol;
      import org.apache.thrift.transport.TFramedTransport;
      import org.apache.thrift.transport.TSocket;
      import org.apache.thrift.transport.TTransport;
      import org.apache.thrift.transport.TTransportException;
    
      public class ThriftClient {
    
          private static int port = 8089;
    
          public static void main(String[] args) {
              try {
      //              -----------單線程阻塞io類型-----------------------
      //            TTransport transport = new TFramedTransport(new TSocket("127.0.0.1",port , 5000));
      //            TProtocol protocol = new TBinaryProtocol(transport);
      //            GeneralThriftService.Client client = new GeneralThriftService.Client(protocol);
      //            transport.open();
      //            String string = client.generalService("request paramter");
      //            System.out.println(string);
      //            transport.close();
      //            -------------------------------------------------------
      //            使用非阻塞式IO,服務端和客戶端須要指定TFramedTransport數據傳輸的方式
      //            TTransport transport = new TFramedTransport(new TSocket("127.0.0.1",port , 5000));
      //            TProtocol protocol = new TCompactProtocol(transport);
      //            GeneralThriftService.Client client = new GeneralThriftService.Client(protocol);
      //            transport.open();
      //            String string = client.generalService("request paramter");
      //            System.out.println(string);
      //            transport.close();
      //          使用非阻塞式IO,服務端和客戶端須要指定TFramedTransport數據傳輸的方式
      //            TTransport transport = new TFramedTransport(new TSocket("127.0.0.1",port , 5000));
      //            TProtocol protocol = new TCompactProtocol(transport);
      //            GeneralThriftService.Client client = new GeneralThriftService.Client(protocol);
      //            transport.open();
      //            String string = client.generalService("request paramter");
      //            System.out.println(string);
      //            transport.close();
      //          使用非阻塞式IO,服務端和客戶端須要指定TFramedTransport數據傳輸的方式
                  TTransport transport = new TFramedTransport(new TSocket("127.0.0.1",port , 5000));
                  TProtocol protocol = new TCompactProtocol(transport);
                  GeneralThriftService.Client client = new GeneralThriftService.Client(protocol);
                  transport.open();
                  String string = client.generalService("request paramter");
                  System.out.println(string);
                  transport.close();
              } catch (TTransportException e) {
                  e.printStackTrace();
              } catch (TException e) {
                  e.printStackTrace();
              }
          }
      }
  7. 結果
    image.png

參考

相關文章
相關標籤/搜索