thrift学习

Posted Java技术汇

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了thrift学习相关的知识,希望对你有一定的参考价值。

版权声明:本文为图灵学院白起老师原创文章,未经允许不得转载。


Thrift简介


目前个人理解thrift有两方面的东西:

1.      thrift是一个rpc服务框架,支持这种服务器-客户端之间的一种交互操作的框架
此部分有关于对数据传输的序列化和反序列化也是thrift功能的一部分

2.      thrift有自己的一套规范定义IDL的东西,可以根据简介的描述文件来根据thrift编译器自动生成对应的接口类等。

 

 

因为thrift有linux的客户端,windows客户端的编译器。所以正常开发很方便。

因为thrift编译器能自动生成我们对应各种语言的接口实现类等。所以在多语言的交互系统中存在着很大的优势。

 

 

 

 

官方会有简单的实例: http://thrift.apache.org/

Windows的编译器:http://www.apache.org/dyn/closer.cgi?path=/thrift/0.9.2/thrift-0.9.2.exe

C++实例:http://blog.csdn.net/poechant/article/details/6618284

Java实例:http://www.ibm.com/developerworks/cn/java/j-lo-apachethrift/

简单介绍IDL:

http://blog.sina.com.cn/s/blog_78fca7fa01010k7j.html
http://www.cnblogs.com/tianhuilove/archive/2011/09/05/2167669.html

 

 

Windows安装编译器

 

把下载的thrift-xxx-.exe文件copy到我们自己习惯的程序目录,比如:

放到D:\machine\thrift

改下名或者copy一个新文件保证能找到

D:\machine\thrift\thrift.exe

 

比如:



为了以后使用方便,配置下环境变量吧


thrift学习


启动cmd,命令行试下有了thrift命令了。


thrift学习


到此处基本上windows上编译环境就搞定了,然后开始写脚本和写程序了



开发thrift程序

1.     helloWorld


新建maven项目


thrift学习


Pom依赖


[html] view plain copy

  1. <!-- thrift依赖 -->  

  2.         <dependency>  

  3.             <groupId>org.apache.thrift</groupId>  

  4.             <artifactId>libthrift</artifactId>  

  5.             <version>0.9.2</version>  

  6.         </dependency>  

  7. <dependency>  

  8.             <groupId>org.slf4j</groupId>  

  9.             <artifactId>slf4j-api</artifactId>  

  10.             <version>1.7.7</version>  

  11.         </dependency>  

  12.     </dependencies>  





写一个接口脚本:hello.thrift



[html] view plain copy

  1. namespace java com.ruishenh.thrift.hello  

  2.  service Hello{   

  3.   string helloString(1:string para)   

  4.   i32 helloInt(1:i32 para)   

  5.   bool helloBoolean(1:bool para)   

  6.   void helloVoid()   

  7.   string helloNull()   

  8.  }  


 

在对应文件夹执行:

thrift --gen java hello.thrift


thrift学习



这时如果不报错,就会在同级目录下生成gen-java文件,里面会有代码

直接copy到项目的src/main/java目录下

 


写自己业务的实现类:

com.ruishenh.thrift.hello.HelloServiceImpl



[java] view plain copy

  1. package com.ruishenh.thrift.hello;  

  2.   

  3. import org.apache.thrift.TException;  

  4.   

  5. public class HelloServiceImpl implements Hello.Iface {  

  6.     @Override  

  7.     public boolean helloBoolean(boolean para) throws TException {  

  8.         return para;  

  9.     }  

  10.   

  11.     @Override  

  12.     public int helloInt(int para) throws TException {  

  13.         try {  

  14.             Thread.sleep(20000);  

  15.         } catch (InterruptedException e) {  

  16.             e.printStackTrace();  

  17.         }  

  18.         return para;  

  19.     }  

  20.   

  21.     @Override  

  22.     public String helloNull() throws TException {  

  23.         return null;  

  24.     }  

  25.   

  26.     @Override  

  27.     public String helloString(String para) throws TException {  

  28.         return para+":metoo!";  

  29.     }  

  30.   

  31.     @Override  

  32.     public void helloVoid() throws TException {  

  33.         System.out.println("Hello World");  

  34.     }  

  35. }  





写服务器类

com.ruishenh.thrift.hello.HelloServiceServer



[java] view plain copy

  1. package com.ruishenh.thrift.hello;  

  2.   

  3. import java.net.InetSocketAddress;  

  4.   

  5. import org.apache.thrift.protocol.TBinaryProtocol;  

  6. import org.apache.thrift.server.TServer;  

  7. import org.apache.thrift.server.TThreadPoolServer;  

  8. import org.apache.thrift.server.TThreadPoolServer.Args;  

  9. import org.apache.thrift.transport.TServerSocket;  

  10. import org.apache.thrift.transport.TTransportFactory;  

  11.   

  12. public class HelloServiceServer {  

  13.     public static void main(String[] args) {  

  14.         // TODO Auto-generated method stub  

  15.         Hello.Processor<Hello.Iface> processor = new Hello.Processor<Hello.Iface>(new HelloServiceImpl());  

  16.         try {  

  17.             TServerSocket serverTransport = new TServerSocket(new InetSocketAddress("0.0.0.0"9813));  

  18.             Args trArgs = new Args(serverTransport);  

  19.             trArgs.processor(processor);  

  20.             // 使用二进制来编码应用层的数据  

  21.             trArgs.protocolFactory(new TBinaryProtocol.Factory(truetrue));  

  22.             // 使用普通的socket来传输数据  

  23.             trArgs.transportFactory(new TTransportFactory());  

  24.             TServer server = new TThreadPoolServer(trArgs);  

  25.             System.out.println("server begin ......................");  

  26.             server.serve();  

  27.             System.out.println("---------------------------------------");  

  28.             server.stop();  

  29.         } catch (Exception e) {  

  30.             throw new RuntimeException("index thrift server start failed!!" + "/n" + e.getMessage());  

  31.         }  

  32.     }  

  33. }  





写客户端类

com.ruishenh.thrift.hello.HelloServiceClient



[java] view plain copy

  1. package com.ruishenh.thrift.hello;  

  2.   

  3. import org.apache.thrift.TException;  

  4. import org.apache.thrift.protocol.TBinaryProtocol;  

  5. import org.apache.thrift.protocol.TProtocol;  

  6. import org.apache.thrift.transport.TSocket;  

  7. import org.apache.thrift.transport.TTransport;  

  8.   

  9. public class HelloServiceClient {  

  10.     /** 

  11.      * @param args 

  12.      * @throws TException 

  13.      */  

  14.     public static void main(String[] args) throws TException {  

  15.         // TODO Auto-generated method stub  

  16.         TTransport transport = new TSocket("10.144.32.115"9813);  

  17.         long start = System.currentTimeMillis();  

  18.         TProtocol protocol = new TBinaryProtocol(transport);  

  19.         Hello.Client client = new Hello.Client(protocol);  

  20.         transport.open();  

  21.   

  22.         String helloString = client.helloString("hello-world~");  

  23.         System.out.println(helloString);  

  24.         transport.close();  

  25.         System.out.println((System.currentTimeMillis() - start));  

  26.         System.out.println("client sucess!");  

  27.     }  

  28. }  





运行效果:

 

服务器启动:

thrift学习


客户端启动:


thrift学习



2.     ParamObject(对象参数)



thrift学习




定义带对象参数的接口文件paramObject.thrift



[html] view plain copy

  1. namespace java com.ruishenh.thrift.paramObject  

  2.  service OrderService{  //订单接口  

  3.   i32 createOrder(1:Order order) //创建订单  

  4.   Order getOrder(1:Order order) //获取订单  

  5.  }  

  6.    

  7.  struct Order{   //订单信息  

  8.  1: i32 orderId,    

  9.  2: string skuName,    

  10.  3: bool hasIns,  

  11.  4: string remark,    

  12.  5: i16 status,    

  13. }  



生成步骤和helloword一样,server和client写法也一样,

 

运行效果:




1.     序列化


正常的序列化我们其实不用做什么,因为thrift的rpc框架已经帮我们做了,但是有时候我们如果需要自己动手序列化到文件或者其他存储设备还是有可能的。

 

 

测试类:

com.ruishenh.thrift.paramObject.SerializeTest

 

 

运行效果:

代码:


[java] view plain copy

  1. package com.ruishenh.thrift.paramObject;  

  2.   

  3. import java.io.File;  

  4. import java.io.FileInputStream;  

  5. import java.io.FileNotFoundException;  

  6. import java.io.FileOutputStream;  

  7. import java.io.IOException;  

  8.   

  9. import org.apache.thrift.TException;  

  10. import org.apache.thrift.protocol.TBinaryProtocol;  

  11. import org.apache.thrift.transport.TiostreamTransport;  

  12.   

  13. public class SerializeTest {  

  14.     public static void main(String[] args) {  

  15.         Order order = new Order();  

  16.         order.setHasIns(true);  

  17.         order.setRemark("麻烦送货速度~");  

  18.         order.setSkuName("高级电饭锅");  

  19.         order.setStatus((short1);  

  20.         String datafile = "D:/xxx.data";  

  21.         write2File(order, datafile);  

  22.         Order readFile2Object = readFile2Object(datafile);  

  23.   

  24.         System.out.println("反序列化前对象:" + order);  

  25.         System.out.println("反序列化后对象:" + readFile2Object);  

  26.     }  

  27.   

  28.     private static Order readFile2Object(String datafile) {  

  29.         try {  

  30.             FileInputStream fis = new FileInputStream(new File(datafile));  

  31.             Order order2 = new Order();  

  32.             order2.read(new TBinaryProtocol(new TIOStreamTransport(fis)));  

  33.             fis.close();  

  34.             return order2;  

  35.         } catch (FileNotFoundException e) {  

  36.             // TODO Auto-generated catch block  

  37.             e.printStackTrace();  

  38.         } catch (TException e) {  

  39.             // TODO Auto-generated catch block  

  40.             e.printStackTrace();  

  41.         } catch (IOException e) {  

  42.             // TODO Auto-generated catch block  

  43.             e.printStackTrace();  

  44.         }  

  45.         return null;  

  46.     }  

  47.   

  48.     private static void write2File(Order order, String datafile) {  

  49.         try {  

  50.             FileOutputStream fos = new FileOutputStream(new File(datafile));  

  51.             order.write(new TBinaryProtocol(new TIOStreamTransport(fos)));  

  52.             fos.close();  

  53.         } catch (FileNotFoundException e) {  

  54.             // TODO Auto-generated catch block  

  55.             e.printStackTrace();  

  56.         } catch (TException e) {  

  57.             // TODO Auto-generated catch block  

  58.             e.printStackTrace();  

  59.         } catch (IOException e) {  

  60.             // TODO Auto-generated catch block  

  61.             e.printStackTrace();  

  62.         }  

  63.     }  

  64. }  

推荐阅读


thrift学习
微信号:bitedu2015


以上是关于thrift学习的主要内容,如果未能解决你的问题,请参考以下文章

[ToDo]Thrift学习

Thrift快速入门

Thrift 源码学习一

Thrift学习总结

RPC协议学习手记:thrift

Workman-Thrift疑问解析