1.简介
常见的服务调用有基于soap的web service方式,也有基于restful方式的接口方式,数据传输格式有json和xml,xml方式传输数据效率相对较低,json方式体积小,相对不够完善。Facebook 开发的远程服务调用框架 Apache Thrift,它采用接口描述语言定义并创建服务,支持可扩展的跨语言服务开发,所包含的代码生成引擎可以在多种语言中,如 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk 等创建高效的、无缝的服务,其传输数据采用二进制格式,相对 XML 和 JSON 体积更小,对于高并发、大数据量和多语言的环境更有优势。--来自
2.thrift原理
TTransport层:代表thrift的数据传输方式,thrift定义了如下几种常用数据传输方式
- TSocket: 阻塞式socket;
- TFramedTransport: 以frame为单位进行传输,非阻塞式服务中使用;
- TFileTransport: 以文件形式进行传输;
TProtocol层:代表thrift客户端和服务端之间传输数据的协议,通俗来讲就是客户端和服务端之间传输数据的格式(例如json等),thrift定义了如下几种常见的格式
- TBinaryProtocol: 二进制格式;
- TCompactProtocol: 压缩格式;
- TJSONProtocol: JSON格式;
- TSimpleJSONProtocol: 提供只写的JSON协议;
thrift支持的Server模型
- TSimpleServer: 简单的单线程服务模型,常用于测试;
- TThreadPoolServer: 多线程服务模型,使用标准的阻塞式IO;
- TNonBlockingServer: 多线程服务模型,使用非阻塞式IO(需要使用TFramedTransport数据传输方式);
- THsHaServer: THsHa引入了线程池去处理,其模型读写任务放到线程池去处理,Half-sync/Half-async处理模式,Half-async是在处理IO事件上(accept/read/write io),Half-sync用于handler对rpc的同步处理;
3.使用流程
- 在windows上下载编译器
-
编写thrift idl文件
文件名:GeneralInterface.thrift namespace java com.xiayu.thrift service GeneralThriftService{ string generalService(1:string generalPar) }
-
生成java文件
thrift-0.13.0.exe -r -gen java ./GeneralInterface.thrift
-
项目中加入thrift依赖(maven)
<dependency> <groupId>org.apache.thrift</groupId> <artifactId>libthrift</artifactId> <version>0.13.0</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.5</version> </dependency>
-
服务端
package com.xiayu.thrift; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TCompactProtocol; import org.apache.thrift.server.*; import org.apache.thrift.transport.*; public class ThriftServer { private static int port = 8089; public static void main(String[] args) { try { // -----------单线程阻塞io类型----------------------- // TProcessor processor = new GeneralThriftService.Processor<GeneralThriftService.Iface>(new ThriftGeneralService()); // TServerSocket serverTransport = new TServerSocket(port); // TTransportFactory transportFactory = new TFramedTransport.Factory(); // TBinaryProtocol.Factory factory = new TBinaryProtocol.Factory(); // TServer.Args tArgs = new TServer.Args(serverTransport); // tArgs.protocolFactory(factory); // tArgs.transportFactory(transportFactory); // tArgs.processor(processor); // TServer server = new TSimpleServer(tArgs); // server.serve(); // System.out.println("Thrift Server started"); // ------------------------------------- // 使用非阻塞式IO,服务端和客户端需要指定TFramedTransport数据传输的方式 // TProcessor processor = new GeneralThriftService.Processor<GeneralThriftService.Iface>(new ThriftGeneralService()); // TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(port); // TNonblockingServer.Args tnbArgs = new TNonblockingServer.Args(tnbSocketTransport); // tnbArgs.processor(processor); // tnbArgs.transportFactory(new TFramedTransport.Factory()); // tnbArgs.protocolFactory(new TCompactProtocol.Factory()); // TServer server = new TNonblockingServer(tnbArgs); // server.serve(); // ------------------------------------- // 使用非阻塞式IO,服务端和客户端需要指定TFramedTransport数据传输的方式 // TProcessor processor = new GeneralThriftService.Processor<GeneralThriftService.Iface>(new ThriftGeneralService()); // TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(port); // TNonblockingServer.Args tnbArgs = new TNonblockingServer.Args(tnbSocketTransport); // tnbArgs.processor(processor); // tnbArgs.transportFactory(new TFramedTransport.Factory()); // tnbArgs.protocolFactory(new TCompactProtocol.Factory()); // TServer server = new TNonblockingServer(tnbArgs); // server.serve(); // 使用非阻塞式IO,服务端和客户端需要指定TFramedTransport数据传输的方式 TProcessor processor = new GeneralThriftService.Processor<GeneralThriftService.Iface>(new ThriftGeneralService()); TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(port); TNonblockingServer.Args tnbArgs = new TNonblockingServer.Args(tnbSocketTransport); tnbArgs.processor(processor); tnbArgs.transportFactory(new TFramedTransport.Factory()); tnbArgs.protocolFactory(new TCompactProtocol.Factory()); TServer server = new TNonblockingServer(tnbArgs); server.serve(); } catch (TTransportException e) { System.out.println("Starting Thrift Server......Error!!!"); e.printStackTrace(); } } }
-
客户端
package com.xiayu.thrift; import org.apache.thrift.TException; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TCompactProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.transport.TFramedTransport; import org.apache.thrift.transport.TSocket; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; public class ThriftClient { private static int port = 8089; public static void main(String[] args) { try { // -----------单线程阻塞io类型----------------------- // TTransport transport = new TFramedTransport(new TSocket("127.0.0.1",port , 5000)); // TProtocol protocol = new TBinaryProtocol(transport); // GeneralThriftService.Client client = new GeneralThriftService.Client(protocol); // transport.open(); // String string = client.generalService("request paramter"); // System.out.println(string); // transport.close(); // ------------------------------------------------------- // 使用非阻塞式IO,服务端和客户端需要指定TFramedTransport数据传输的方式 // TTransport transport = new TFramedTransport(new TSocket("127.0.0.1",port , 5000)); // TProtocol protocol = new TCompactProtocol(transport); // GeneralThriftService.Client client = new GeneralThriftService.Client(protocol); // transport.open(); // String string = client.generalService("request paramter"); // System.out.println(string); // transport.close(); // 使用非阻塞式IO,服务端和客户端需要指定TFramedTransport数据传输的方式 // TTransport transport = new TFramedTransport(new TSocket("127.0.0.1",port , 5000)); // TProtocol protocol = new TCompactProtocol(transport); // GeneralThriftService.Client client = new GeneralThriftService.Client(protocol); // transport.open(); // String string = client.generalService("request paramter"); // System.out.println(string); // transport.close(); // 使用非阻塞式IO,服务端和客户端需要指定TFramedTransport数据传输的方式 TTransport transport = new TFramedTransport(new TSocket("127.0.0.1",port , 5000)); TProtocol protocol = new TCompactProtocol(transport); GeneralThriftService.Client client = new GeneralThriftService.Client(protocol); transport.open(); String string = client.generalService("request paramter"); System.out.println(string); transport.close(); } catch (TTransportException e) { e.printStackTrace(); } catch (TException e) { e.printStackTrace(); } } }
- 结果
参考
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。