Apache Thrift原理及windows使用

来源:互联网 发布:win8连接网络打印机 编辑:程序博客网 时间:2024/06/11 05:44

本文旨在全面的介绍thrift的使用流程,

使用的例子为一个简单的加法服务程序,从客户端发送请求及操作数,服务器端返回加法结果


一、安装篇:

windows:

1. 直接下载windows版本的thrift编译器,http://archive.apache.org/dist/thrift/0.9.0/thrift-0.9.0.exe  

下载完成后,将其改名为thrift,并将安装路径添加到系统环境变量PATH中。


2. 下载相应的源码,生成jar包  (详细过程:http://f.dataguru.cn/thread-68637-1-1.html)

注意:thrift编译器的版本必须与相应的jar包版本相同。在windows下生成jar包比较麻烦,此处提供0.9.0版本的jar包供大家使用,上步中下载的编译器也为0.9.0版本

url:


3. 下载org.apache.http及org.apache.commons.logging

http://commons.apache.org/proper/commons-logging/download_logging.cgi

http://hc.apache.org/downloads.cgi


4. 下载slf4j jar包

http://www.slf4j.org/download.html


最后将相应的jar包都添加入eclipse工程的external jars, 就完成了我们的配置工作。



二、.thrift 文件篇:

该文件用于定义所需的数据结构及服务接口。(常用介绍,更详细的范例可以参考https://git-wip-us.apache.org/repos/asf/thrift/?p=thrift.git;a=blob;f=tutorial/tutorial.thrift;h=3150151deceb87e22123c9a321d9cd000dcfce5b;hb=HEAD )

1. 基本数据结构:

bool        Boolean, one bytebyte        Signed bytei16         Signed 16-bit integeri32         Signed 32-bit integeri64         Signed 64-bit integerdouble      64-bit floating point valuestring      Stringbinary      Blob (byte array)map<t1,t2>  Map from one type to anotherlist<t1>    Ordered list of one typeset<t1>     Set of unique elements of one type

更改基本数据结构类型名:
typedef i32 MyInteger

定义常量:
const i32 INT32CONSTANT = 9853

定义结构体:
struct Work {1: i32 num1 = 0,2: i32 num2,3: Operation op,4: optional string comment,// optional选项表示如果该变量的值没有被set,它就不会出现在串行化输出中}


2. 定义服务:
service Calculator extends shared.SharedService {/*** A method definition looks like C code. It has a return type, arguments,* and optionally a list of exceptions that it may throw. Note that argument* lists and exception lists are specified using the exact same syntax as* field lists in struct or exception definitions.*/void ping(),i32 add(1:i32 num1, 2:i32 num2),i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch),/*** This method has a oneway modifier. That means the client only makes* a request and does not listen for any response at all. Oneway methods* must be void.*/oneway void zip()}


我们的thrift文件:
namespace java com.baidu.thrift     // 定义输出的语言类型及所属packageservice Calculator{                 // 定义服务    i32 add(1:i32 num1,2:i32 num2)}


三、服务处理函数篇
我们的服务处理函数
package com.baidu.thrift;import com.baidu.thrift.Calculator.Iface;// 格式为 package.服务名.Ifaceimport org.apache.thrift.TException;public class CalculatorHandler implements Iface{@Overridepublic int add(int num1,int num2) throws TException{//重载我们在服务中定义的函数addreturn num1+num2;}}


四、服务器篇
package com.baidu.thrift;import org.apache.thrift.protocol.TBinaryProtocol;import org.apache.thrift.protocol.TBinaryProtocol.Factory;import org.apache.thrift.server.TServer;import org.apache.thrift.server.TThreadPoolServer;import org.apache.thrift.server.TThreadPoolServer.Args;import org.apache.thrift.transport.TNonblockingServerSocket;import org.apache.thrift.transport.TTransportException;// import the processor of serviceimport com.baidu.thrift.Calculator;public class JavaServer {public final static int PORT = 10005;public void startServer(){try {// 定义socketTNonblockingServerSocket socket = new TNonblockingServerSocket(PORT);// 定义服务的处理器,语句格式比较固定final Calculator.Processor processor = new Calculator.Processor(new CalculatorHandler());// 定义协议Factory portFactory = new TBinaryProtocol.Factory(true,true);// 填充参数Args args = new Args(socket);args.processor(processor);args.protocolFactory(portFactory);// 创建serverTServer server = new TThreadPoolServer(args);server.serve();}catch(TTransportException e){e.printStackTrace();}}public static void main(String[] args){System.out.println("Server inits ...");JavaServer server  = new JavaServer();System.out.println("Server starts ...");server.startServer();System.out.println("Completed");}}

五、客户端篇
package com.baidu.thrift;import org.apache.thrift.TException;import org.apache.thrift.protocol.TBinaryProtocol;import org.apache.thrift.protocol.TProtocol;import org.apache.thrift.transport.TSocket;import org.apache.thrift.transport.TTransport;import org.apache.thrift.transport.TTransportException;public class JavaClient {    public void startClient() {          TTransport transport;          try {              System.out.println("thrift client starts ");            transport = new TSocket("localhost", JavaServer.PORT);              TProtocol protocol = new TBinaryProtocol(transport);              Calculator.Client client = new Calculator.Client(protocol);              transport.open();              System.out.println(client.add(10, 20));              transport.close();              System.out.println("Client closes");        } catch (TTransportException e) {              e.printStackTrace();          } catch (TException e) {              e.printStackTrace();          }      }        public static void main(String[] args) {      System.out.println("thrift client inits ");        JavaClient client = new JavaClient();          System.out.println("thrift client starts ");        client.startClient();          System.out.println("thrift client ends ");    }  }

注意: 定义的协议与端口需要与server端一致。最后通过client.服务 调用我们所要使用的服务


原理:
在http://www.ibm.com/developerworks/cn/java/j-lo-apachethrift/ 上有较好的说明,不赘述。