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
比如:
为了以后使用方便,配置下环境变量吧
启动cmd,命令行试下有了thrift命令了。
到此处基本上windows上编译环境就搞定了,然后开始写脚本和写程序了
开发thrift程序
1. helloWorld
新建maven项目
Pom依赖
[html] view plain copy
<!-- thrift依赖 -->
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.9.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency>
</dependencies>
写一个接口脚本:hello.thrift
[html] view plain copy
namespace java com.ruishenh.thrift.hello
service Hello{
string helloString(1:string para)
i32 helloInt(1:i32 para)
bool helloBoolean(1:bool para)
void helloVoid()
string helloNull()
}
在对应文件夹执行:
thrift --gen java hello.thrift
这时如果不报错,就会在同级目录下生成gen-java文件,里面会有代码
直接copy到项目的src/main/java目录下
写自己业务的实现类:
com.ruishenh.thrift.hello.HelloServiceImpl
[java] view plain copy
package com.ruishenh.thrift.hello;
import org.apache.thrift.TException;
public class HelloServiceImpl implements Hello.Iface {
@Override
public boolean helloBoolean(boolean para) throws TException {
return para;
}
@Override
public int helloInt(int para) throws TException {
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return para;
}
@Override
public String helloNull() throws TException {
return null;
}
@Override
public String helloString(String para) throws TException {
return para+":metoo!";
}
@Override
public void helloVoid() throws TException {
System.out.println("Hello World");
}
}
写服务器类
com.ruishenh.thrift.hello.HelloServiceServer
[java] view plain copy
package com.ruishenh.thrift.hello;
import java.net.InetSocketAddress;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.server.TThreadPoolServer.Args;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TTransportFactory;
public class HelloServiceServer {
public static void main(String[] args) {
// TODO Auto-generated method stub
Hello.Processor<Hello.Iface> processor = new Hello.Processor<Hello.Iface>(new HelloServiceImpl());
try {
TServerSocket serverTransport = new TServerSocket(new InetSocketAddress("0.0.0.0", 9813));
Args trArgs = new Args(serverTransport);
trArgs.processor(processor);
// 使用二进制来编码应用层的数据
trArgs.protocolFactory(new TBinaryProtocol.Factory(true, true));
// 使用普通的socket来传输数据
trArgs.transportFactory(new TTransportFactory());
TServer server = new TThreadPoolServer(trArgs);
System.out.println("server begin ......................");
server.serve();
System.out.println("---------------------------------------");
server.stop();
} catch (Exception e) {
throw new RuntimeException("index thrift server start failed!!" + "/n" + e.getMessage());
}
}
}
写客户端类
com.ruishenh.thrift.hello.HelloServiceClient
[java] view plain copy
package com.ruishenh.thrift.hello;
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;
public class HelloServiceClient {
/**
* @param args
* @throws TException
*/
public static void main(String[] args) throws TException {
// TODO Auto-generated method stub
TTransport transport = new TSocket("10.144.32.115", 9813);
long start = System.currentTimeMillis();
TProtocol protocol = new TBinaryProtocol(transport);
Hello.Client client = new Hello.Client(protocol);
transport.open();
String helloString = client.helloString("hello-world~");
System.out.println(helloString);
transport.close();
System.out.println((System.currentTimeMillis() - start));
System.out.println("client sucess!");
}
}
运行效果:
服务器启动:
客户端启动:
2. ParamObject(对象参数)
定义带对象参数的接口文件paramObject.thrift
[html] view plain copy
namespace java com.ruishenh.thrift.paramObject
service OrderService{ //订单接口
i32 createOrder(1:Order order) //创建订单
Order getOrder(1:Order order) //获取订单
}
struct Order{ //订单信息
1: i32 orderId,
2: string skuName,
3: bool hasIns,
4: string remark,
5: i16 status,
}
生成步骤和helloword一样,server和client写法也一样,
运行效果:
1. 序列化
正常的序列化我们其实不用做什么,因为thrift的rpc框架已经帮我们做了,但是有时候我们如果需要自己动手序列化到文件或者其他存储设备还是有可能的。
测试类:
com.ruishenh.thrift.paramObject.SerializeTest
运行效果:
代码:
[java] view plain copy
package com.ruishenh.thrift.paramObject;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.transport.TiostreamTransport;
public class SerializeTest {
public static void main(String[] args) {
Order order = new Order();
order.setHasIns(true);
order.setRemark("麻烦送货速度~");
order.setSkuName("高级电饭锅");
order.setStatus((short) 1);
String datafile = "D:/xxx.data";
write2File(order, datafile);
Order readFile2Object = readFile2Object(datafile);
System.out.println("反序列化前对象:" + order);
System.out.println("反序列化后对象:" + readFile2Object);
}
private static Order readFile2Object(String datafile) {
try {
FileInputStream fis = new FileInputStream(new File(datafile));
Order order2 = new Order();
order2.read(new TBinaryProtocol(new TIOStreamTransport(fis)));
fis.close();
return order2;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
private static void write2File(Order order, String datafile) {
try {
FileOutputStream fos = new FileOutputStream(new File(datafile));
order.write(new TBinaryProtocol(new TIOStreamTransport(fos)));
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
推荐阅读
以上是关于thrift学习的主要内容,如果未能解决你的问题,请参考以下文章