您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 冶金工业 > ApacheThrift-跨语言远程服务调用框架
ApacheThrift-跨语言远程服务调用框架简介:ApacheThrift是Facebook实现的一种高效的、支持多种编程语言的远程服务调用的框架。本文将从Java开发人员角度详细介绍ApacheThrift的架构、开发和部署,并且针对不同的传输协议和服务类型给出相应的Java实例,同时详细介绍Thrift异步客户端的实现,最后提出使用Thrift需要注意的事项。前言:目前流行的服务调用方式有很多种,例如基于SOAP消息格式的WebService,基于JSON消息格式的RESTful服务等。其中所用到的数据传输方式包括XML,JSON等,然而XML相对体积太大,传输效率低,JSON体积较小,新颖,但还不够完善。本文将介绍由Facebook开发的远程服务调用框架ApacheThrift,它采用接口描述语言定义并创建服务,支持可扩展的跨语言服务开发,所包含的代码生成引擎可以在多种语言中,如C++,Java,Python,PHP,Ruby,Erlang,Perl,Haskell,C#,Cocoa,Smalltalk等创建高效的、无缝的服务,其传输数据采用二进制格式,相对XML和JSON体积更小,对于高并发、大数据量和多语言的环境更有优势。本文将详细介绍Thrift的使用,并且提供丰富的实例代码加以解释说明,帮助使用者快速构建服务。回页首一个简单的Thrift实例本文首先介绍一个简单的Thrift实现实例,使读者能够快速直观地了解什么是Thrift以及如何使用Thrift构建服务。创建一个简单的服务Hello。首先根据Thrift的语法规范编写脚本文件Hello.thrift,代码如下:清单1.Hello.thriftnamespacejavaservice.demoserviceHello{stringhelloString(1:stringpara)i32helloInt(1:i32para)boolhelloBoolean(1:boolpara)voidhelloVoid()stringhelloNull()}其中定义了服务Hello的五个方法,每个方法包含一个方法名,参数列表和返回类型。每个参数包括参数序号,参数类型以及参数名。Thrift是对IDL(InterfaceDefinitionLanguage)描述性语言的一种具体实现。因此,以上的服务描述文件使用IDL语法编写。使用Thrift工具编译Hello.thrift,就会生成相应的Hello.java文件。该文件包含了在Hello.thrift文件中描述的服务Hello的接口定义,即Hello.Iface接口,以及服务调用的底层通信细节,包括客户端的调用逻辑Hello.Client以及服务器端的处理逻辑Hello.Processor,用于构建客户端和服务器端的功能。创建HelloServiceImpl.java文件并实现Hello.java文件中的Hello.Iface接口,代码如下:清单2.HelloServiceImpl.javapackageservice.demo;importorg.apache.thrift.TException;publicclassHelloServiceImplimplementsHello.Iface{@OverridepublicbooleanhelloBoolean(booleanpara)throwsTException{returnpara;}@OverridepublicinthelloInt(intpara)throwsTException{try{Thread.sleep(20000);}catch(InterruptedExceptione){e.printStackTrace();}returnpara;}@OverridepublicStringhelloNull()throwsTException{returnnull;}@OverridepublicStringhelloString(Stringpara)throwsTException{returnpara;}@OverridepublicvoidhelloVoid()throwsTException{System.out.println(HelloWorld);}}创建服务器端实现代码,将HelloServiceImpl作为具体的处理器传递给Thrift服务器,代码如下:清单3.HelloServiceServer.javapackageservice.server;importorg.apache.thrift.TProcessor;importorg.apache.thrift.protocol.TBinaryProtocol;importorg.apache.thrift.protocol.TBinaryProtocol.Factory;importorg.apache.thrift.server.TServer;importorg.apache.thrift.server.TThreadPoolServer;importorg.apache.thrift.transport.TServerSocket;importorg.apache.thrift.transport.TTransportException;importservice.demo.Hello;importservice.demo.HelloServiceImpl;publicclassHelloServiceServer{/***启动Thrift服务器*@paramargs*/publicstaticvoidmain(String[]args){try{//设置服务端口为7911TServerSocketserverTransport=newTServerSocket(7911);//设置协议工厂为TBinaryProtocol.FactoryFactoryproFactory=newTBinaryProtocol.Factory();//关联处理器与Hello服务的实现TProcessorprocessor=newHello.Processor(newHelloServiceImpl());TServerserver=newTThreadPoolServer(processor,serverTransport,proFactory);System.out.println(Startserveronport7911...);server.serve();}catch(TTransportExceptione){e.printStackTrace();}}}创建客户端实现代码,调用Hello.client访问服务端的逻辑实现,代码如下:清单4.HelloServiceClient.javapackageservice.client;importorg.apache.thrift.TException;importorg.apache.thrift.protocol.TBinaryProtocol;importorg.apache.thrift.protocol.TProtocol;importorg.apache.thrift.transport.TSocket;importorg.apache.thrift.transport.TTransport;importorg.apache.thrift.transport.TTransportException;importservice.demo.Hello;publicclassHelloServiceClient{/***调用Hello服务*@paramargs*/publicstaticvoidmain(String[]args){try{//设置调用的服务地址为本地,端口为7911TTransporttransport=newTSocket(localhost,7911);transport.open();//设置传输协议为TBinaryProtocolTProtocolprotocol=newTBinaryProtocol(transport);Hello.Clientclient=newHello.Client(protocol);//调用服务的helloVoid方法client.helloVoid();transport.close();}catch(TTransportExceptione){e.printStackTrace();}catch(TExceptione){e.printStackTrace();}}}代码编写完后运行服务器,再启动客户端调用服务Hello的方法helloVoid,在服务器端的控制台窗口输出“HelloWorld”(helloVoid方法实现在控制台打印字符串,没有返回值,所以客户端调用方法后没有返回值输出,读者可以自己尝试其他有返回值方法的调用,其结果可以打印在客户端的控制台窗口)。回页首Thrift架构Thrift包含一个完整的堆栈结构用于构建客户端和服务器端。下图描绘了Thrift的整体架构。图1.架构图如图所示,图中黄色部分是用户实现的业务逻辑,褐色部分是根据Thrift定义的服务接口描述文件生成的客户端和服务器端代码框架,红色部分是根据Thrift文件生成代码实现数据的读写操作。红色部分以下是Thrift的传输体系、协议以及底层I/O通信,使用Thrift可以很方便的定义一个服务并且选择不同的传输协议和传输层而不用重新生成代码。Thrift服务器包含用于绑定协议和传输层的基础架构,它提供阻塞、非阻塞、单线程和多线程的模式运行在服务器上,可以配合服务器/容器一起运行,可以和现有的J2EE服务器/Web容器无缝的结合。服务端和客户端具体的调用流程如下:图2.Server端启动、服务时序图(查看大图)该图所示是HelloServiceServer启动的过程以及服务被客户端调用时,服务器的响应过程。从图中我们可以看到,程序调用了TThreadPoolServer的serve方法后,server进入阻塞监听状态,其阻塞在TServerSocket的accept方法上。当接收到来自客户端的消息后,服务器发起一个新线程处理这个消息请求,原线程再次进入阻塞状态。在新线程中,服务器通过TBinaryProtocol协议读取消息内容,调用HelloServiceImpl的helloVoid方法,并将结果写入helloVoid_result中传回客户端。图3.Client端调用服务时序图(查看大图)该图所示是HelloServiceClient调用服务的过程以及接收到服务器端的返回值后处理结果的过程。从图中我们可以看到,程序调用了Hello.Client的helloVoid方法,在helloVoid方法中,通过send_helloVoid方法发送对服务的调用请求,通过recv_helloVoid方法接收服务处理请求后返回的结果。回页首数据类型Thrift脚本可定义的数据类型包括以下几种类型:基本类型:obool:布尔值,true或false,对应Java的booleanobyte:8位有符号整数,对应Java的byteoi16:16位有符号整数,对应Java的shortoi32:32位有符号整数,对应Java的intoi64:64位有符号整数,对应Java的longodouble:64位浮点数,对应Java的doubleostring:未知编码文本或二进制字符串,对应Java的String结构体类型:ostruct:定义公共的对象,类似于C语言中的结构体定义,在Java中是一个JavaBean容器类型:olist:对应Java的ArrayListoset:对应Java的HashSetomap:对应Java的HashMap异常类型:oexception:对应Java的Excep
本文标题:ApacheThrift-跨语言远程服务调用框架
链接地址:https://www.777doc.com/doc-2897886 .html