RPC框架——Thrift简单示例
1. 简介
- Apache Thrift 是一款RPC框架
- 官方网址: Apache Thrift
- 主要支持: C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, OCaml, Delphi
- Thrift 主要由2部分构成
- 远程过程调用
- 数据序列化/反序列化
2. 将*.thrift 协议文件转换为语言源文件
- 下载Thrift编译器(当前版本 0.13.0)
- 地址: http://thrift.apache.org/download
- windows 点击 Thrift compiler for Windows (thrift-0.13.0.exe) ,其他系统点另一个(自己编译)
- 将下载好的thrift-0.13.0.exe文件配置入系统环境变量
- 帮助文档命令: thrift-0.13.0.exe -help
- 编写 my_protocol.thrift 文件 (官方IDL说明)
// 包名 namespace java com.skey.thriftdemo.thrift // 前面的1,2,3...标识,确定唯一一个数据,解析时用 // required表示必须传入该参数,optional表示可选择传入参数 // 一个JavaBean struct Person { 1: required i32 id, 2: optional string name, 3: optional i16 age } // 编写一个异常 exception MyException { 1: required string msg; 2: required string time; } // 编写RPC调用服务 service PersonService { // 定义一个方法getPeronById,传入id,返回Person,如果发生异常,抛出MyException Person getPeronById(1: required i32 id) throws (1: MyException myException) }
- 编译*.thrift文件,转化为语言源文件
- 命令 thrift-0.13.0.exe --gen 语言 *.thrift文件
- 示例 thrift-0.13.0.exe --gen java .\my_protocol.thrift
- 编译完成后,会再当前目录下生成一个gen-java目录,里面就是我们需要的文件了,将其拷入项目中即可
3. 使用 Thrift 编写服务端/客户端
- 引入Maven依赖(当前版本 0.13.0)
<dependency> <groupId>org.apache.thrift</groupId> <artifactId>libthrift</artifactId> <version>0.13.0</version> </dependency>
- 服务端示例
- PersonServiceImpl.java
package com.skey.thriftdemo; import com.skey.thriftdemo.thrift.MyException; import com.skey.thriftdemo.thrift.Person; import com.skey.thriftdemo.thrift.PersonService; import java.time.LocalDateTime; /** * Description: 服务实现类 * <br/> * Date: 2019/12/18 18:41 * * @author ALion */ public class PersonServiceImpl implements PersonService.Iface { @Override public Person getPeronById(int id) throws MyException { System.out.println("PersonServiceImpl.getPeronById"); if (id > 5) { throw new MyException("No such Person that id > 5", LocalDateTime.now().toString()); } Person person = new Person(); person.setId(id) .setName("laowang") .setAge((short) 28); return person; } }
- ServerDemo.java
package com.skey.thriftdemo; import com.skey.thriftdemo.thrift.PersonService; import org.apache.thrift.TProcessorFactory; import org.apache.thrift.protocol.TCompactProtocol; import org.apache.thrift.server.THsHaServer; import org.apache.thrift.transport.TFastFramedTransport; import org.apache.thrift.transport.TNonblockingServerSocket; import org.apache.thrift.transport.TTransportException; /** * Description: 服务端示例 * <br/> * Date: 2019/12/18 18:38 * * @author ALion */ public class ServerDemo { public static void main(String[] args) { try { TNonblockingServerSocket transport = new TNonblockingServerSocket(10086); PersonService.Processor<PersonServiceImpl> processor = new PersonService.Processor<>( new PersonServiceImpl() ); // 配置Server的参数 THsHaServer.Args serverArgs = new THsHaServer.Args(transport) .minWorkerThreads(2) .maxWorkerThreads(4) .protocolFactory(new TCompactProtocol.Factory()) .transportFactory(new TFastFramedTransport.Factory()) .processorFactory(new TProcessorFactory(processor)); // 半同步/半异步的Server THsHaServer server = new THsHaServer(serverArgs); // 启动服务,阻塞 server.serve(); } catch (TTransportException e) { e.printStackTrace(); } } }
- PersonServiceImpl.java
- 客户端示例
- ClientDemo.java
package com.skey.thriftdemo; import com.skey.thriftdemo.thrift.MyException; import com.skey.thriftdemo.thrift.Person; import com.skey.thriftdemo.thrift.PersonService; import org.apache.thrift.TException; import org.apache.thrift.protocol.TCompactProtocol; import org.apache.thrift.transport.TFramedTransport; import org.apache.thrift.transport.TSocket; /** * Description: 客户端示例 * <br/> * Date: 2019/12/18 18:38 * * @author ALion */ public class ClientDemo { public static void main(String[] args) { // 构建客户端 TFramedTransport transport = new TFramedTransport( new TSocket("localhost", 10086), 500 ); TCompactProtocol protocol = new TCompactProtocol(transport); PersonService.Client client = new PersonService.Client(protocol); try { // 打开连接 transport.open(); // 开始RPC调用 for (int i = 0; i < 7; i++) { try { Person person = client.getPeronById(i); System.out.println(person); } catch (MyException e) { e.printStackTrace(); } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } catch (TException e) { e.printStackTrace(); } finally { transport.close(); } } }