Thrift可扩展高性能的通信服务框架

         目前流行的服务调用方式有很多种,例如基于 SOAP 消息格式的 Web Service,基于 JSON 消息格式的 RESTful 服务等。其中所用到的数据传输方式包括 XML,JSON 等,然而 XML 相对体积太大,传输效率低,JSON 体积较小,新颖,但还不够完善。本文将介绍由 Facebook 开发的远程服务调用框架 Apache Thrift,它采用接口描述语言定义并创建服务,支持可扩展的跨语言服务开发,所包含的代码生成引擎可以在多种语言中,如 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk 等创建高效的、无缝的服务,其传输数据采用二进制格式,相对 XML 和 JSON 体积更小,对于高并发、大数据量和多语言的环境更有优势。本文将详细介绍 Thrift 的使用,并且提供丰富的实例代码加以解释说明,帮助使用者快速构建服务

-----------------------------------分割线----------------------------------------------------------------

1.下载thrift,我们这里下载最新的0.9.0的windows版本。
2. 进入thrift的目录,定义服务描述文件,thrift的服务描述文件以thrift结尾,类似于web services的wsdl文件。thrift提供了丰富的数据接口用于不同语言之间的服务需求。其数据结构如下
      Base Types:基本类型            

bool:布尔值,true 或 false,对应 Java 的 boolean
byte:8 位有符号整数,对应 Java 的 byte
i16:16 位有符号整数,对应 Java 的 short
i32:32 位有符号整数,对应 Java 的 int
i64:64 位有符号整数,对应 Java 的 long
double:64 位浮点数,对应 Java 的 double
string:未知编码文本或二进制字符串,对应 Java 的 String

      Struct:结构体类型
      Container:容器类型,即List、Set、Map
      Exception:异常类型
      Service: 定义对象的接口,和一系列方法

 

        我们测试定义个叫做Test的服务,其右一个ping方法用户传输一个int32类型的数据。其thrift文件描述如下

namespace java net.johnc.thrift
service Test{
 
 void ping(1: i32 length)
 
}

          可以看到定义了一个叫做Test的服务,并定义了相关方法,其中1:用户标识参数的编号。

    3. 进入thrift的目录,运行$ thrift -r --gen java test.thrift // -r对其中include的文件也生成服务代码 -gen是生成服务代码的语言,此时进入$gen-java的目录下就可以看到生成对应的java文件,该文件即是相应服务端和客户端的实现【其实此处也类似于web services中通过wsdl生成相应代码的情况】。

    4.编写客户端

  

  TTransport transport;
       try {
           transport = new TSocket("localhost", 1234);
           TProtocol protocol = new TBinaryProtocol(transport);
           Test.Client client = new Test.Client(protocol);
           transport.open();
           client.ping(2012);
           transport.close();
       } catch (TTransportException e) {
           e.printStackTrace();
       } catch (TException e) {
           e.printStackTrace();
       }

   如上所示:客户端像服务端调用ping方法,发送2012这个数值

  

   5.编写服务端

    服务实现类TestImpl

  

public class TestImpl implements Test.Iface{

	public void ping(int length) throws TException {
		System.out.println("client length:"+length);
	}

}

    服务启动类Server

   

public class Server {
   public void startServer() {
       try {

           TServerSocket serverTransport = new TServerSocket(1234);

           Test.Processor process = new Processor(new TestImpl());

           Factory portFactory = new TBinaryProtocol.Factory(true, true);

           Args args = new Args(serverTransport);
           args.processor(process);
           args.protocolFactory(portFactory);

           TServer server = new TThreadPoolServer(args);
           server.serve();
       } catch (TTransportException e) {
           e.printStackTrace();
       }
   }

   public static void main(String[] args) {
       Server server = new Server();
       server.startServer();
   }
}

 

    6.分别启动服务端和客户端,即可实现客户端向服务端发送int数值的效果

    从例子中可以看出,thrift的工作流程

   

 FooServeice:是由服务描述文件.thrift 生成而来,不同的语言可以生成不同版本,thrift目前已经支持C++, C#, Cocoa, Erlang, Haskell, Java, Ocami, Perl, PHP, Python, Ruby, Smalltalk等语言(本例中都是以java为例子)

Foo.read()/writer():在服务的下一层提供基础的读写方法,客户端可以向服务端写数据,也可以从服务端接收数据,服务端可以向客户端写数据,也可以向客户端读取数据。

Foo.read()/writer():在服务的下一层提供基础的读写方法,客户端可以向服务端写数据,也可以从服务端接收数据,服务端可以向客户端写数据,也可以向客户端读取数据。

TProcotol:传输协议层,thrift提供了丰富的传输协议,主要包含如下:

TBinaryProtocol – 二进制编码格式进行数据传输。

TCompactProtocol – 这种协议非常有效的,使用Variable-Length Quantity (VLQ) 编码对数据进行压缩。

TJSONProtocol – 使用JSON的数据编码协议进行数据传输。

TSimpleJSONProtocol – 这种节约只提供JSON只写的协议,适用于通过脚本语言解析

TDebugProtocol – 在开发的过程中帮助开发人员调试用的,以文本的形式展现方便阅读。

TTransport:

TSocket- 使用堵塞式I/O进行传输,也是最常见的模式。

TFramedTransport- 使用非阻塞方式,按块的大小,进行传输,类似于Java中的NIO。

TFileTransport- 顾名思义按照文件的方式进程传输,虽然这种方式不提供Java的实现,但是实现起来非常简单。

TMemoryTransport- 使用内存I/O,就好比Java中的ByteArrayOutputStream实现。

TZlibTransport- 使用执行zlib压缩,不提供Java的实现。

服务端在处理客户端请求上也提供多种的模式,包括如下

TSimpleServer:单线程阻塞方式

TThreadPoolServer:多线程阻塞方式
TNonblockingServer:非阻塞的方式以块传输数据

--------------------------------------------------分割线-------------------------------------------------------------

性能测试

协议传输量对比

协议耗费资源对比

猜你喜欢

转载自daoexception.iteye.com/blog/1869822