Thrift介绍(维基百科)
Thrift是一种接口描述语言和二进制通讯协议,[1]它被用来定义和创建跨语言的服务。[2]它被当作一个远程过程调用(RPC)框架来使用,是由Facebook为“大规模跨语言服务开发”而开发的。它通过一个代码生成引擎联合了一个软件栈,来创建不同程度的、无缝的跨平台高效服务,可以使用C#、C++(基于POSIX兼容系统[3])、Cappuccino、[4]Cocoa、Delphi、Erlang、Go、Haskell、Java、Node.js、OCaml、Perl、PHP、Python、Ruby和Smalltalk。[5]虽然它以前是由Facebook开发的,但它现在是Apache软件基金会的开源项目了。该实现被描述在2007年4月的一篇由Facebook发表的技术论文中,该论文现由Apache掌管
准备工作
- 安装:打开terminal,执行brew install thrift(通过brew info thrift查看一下版本,要和项目中pom文件版本一致)
2. 项目依赖:
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.17.0</version>
</dependency>
Thrift使用
- 创建一个thrift文件:
namespace java service.demo
service Hello{
string helloString(1:string para)
}
- terminal进入hello.thrift文件目录,执行生成指令:
thrift -r -gen java Hello.thrift
3.执行之后会多出一个gen目录,里面包括生成的Hello.java文件:
里面包括接口定义Hello.Iface,服务底层通信细节,客户端调用逻辑Hello.Client和服务端处理逻辑Hello.processor(这些都是thrift帮助我们生成好了的)
4.创建Iface借口的实现类,增加实现逻辑
import org.apache.thrift.TException;
public class HelloServiceImpl implements Hello.Iface{
@Override
public String helloString(String para) throws TException {
return "result:" + para;
}
}
5.创建服务端server,将实现类作为hanlder传递给Thrift服务器(processor)
import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TTransportException;
public class HelloServiceServer {
/**
* 启动thrift服务器
*/
public static void main(String[] args) {
System.out.println("服务端开启....");
TProcessor tProcessor = new Hello.Processor<Hello.Iface>(new HelloServiceImpl());
//简单的单线程服务模型
try {
TServerSocket serverTransport = new TServerSocket(9898);
TServer.Args tArgs = new TServer.Args(serverTransport);
tArgs.processor(tProcessor);
tArgs.protocolFactory(new TBinaryProtocol.Factory());
TServer server = new TSimpleServer(tArgs);
server.serve();
} catch (TTransportException e) {
throw new RuntimeException(e);
}
}
}
6.创建客户端client,和server监听同样的端口
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 HelloServiceClient {
public static void main(String[] args) {
System.out.println("客户端启动....");
TTransport transport = null;
try {
transport = new TSocket("localhost", 9898, 30000);
// 协议要和服务端一致
TProtocol protocol = new TBinaryProtocol(transport);
Hello.Client client = new Hello.Client(protocol);
transport.open();
String result = client.helloString("哈哈");
System.out.println(result);
Thread.sleep(300000);
} catch (TTransportException e) {
e.printStackTrace();
} catch (TException e) {
e.printStackTrace();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
if (null != transport) {
transport.close();
}
}
}
}
7.验证
先启动服务端,在启动客户端,客户端console会打印:result:哈哈
RPC & Thrift工作流程
RPC框架本质就是封装除了code部分外的全部其他step,使得开发变得更容易
如上图,Thrift分层(C/S架构),其中Tprotocal是用于数据类型解析的,Ttransport是用于以字节流的方式接收和发送消息体。
Thrift数据类型
基础类型
-
bool:布尔值,true 或 false,对应 Java 的 boolean
-
byte:8 位有符号整数,对应 Java 的 byte
-
i16:16 位有符号整数,对应 Java 的 short
-
i32:32 位有符号整数,对应 Java 的 int
-
i64:64 位有符号整数,对应 Java 的 long
-
double:64 位浮点数,对应 Java 的 double
-
string:utf-8编码的字符串,对应 Java 的 String
结构体类型
- struct:定义公共的对象,类似于 C 语言中的结构体定义,在 Java 中是一个 JavaBean
容器类型
- list:对应 Java 的 ArrayList
- set:对应 Java 的 HashSet
- map:对应 Java 的 HashMap
异常类型
- exception:对应 Java 的 Exception
服务类型
- service:对应服务的类
枚举类型
enum Color{
RED,
BLUE }
命名空间
可以理解成java中的packet,用于避免一些代码冲突,每种语言都有属于自己的命名空间的方式,比如java语言,就可以使用java语言的格式
namespacejava com.DQicy.project
Thrift数据解析协议(TProtocal)
Thrift数据传输分为二进制传输和文本传输,二进制传输在传输速率和节省带宽上更有优势。
- TBinaryProtocol:使用二进制编码格式传输,是thrift的默认传输协议
- TCompactProtocol:使用压缩格式传输
- TJSONProtocol :使用JSON格式传输
- TDebugProtocol – 使用易懂可读的文本格式进行传输,以便于debug
- TSimpleJSONProtocol – 提供JSON只写的协议,适用于通过脚本语言解析
Thrift传输格式(TTransport)
Thrift传输格式分为客户端和服务端。
- TSocket:阻塞式IO的Transport实现,用在客户端.
- TServerSocket:非阻塞式Socket,用于服务器端,用于监听TSocket.
- TNonblockingSocket:非阻塞式IO的实现
- TMemoryInputTransport: 封装了一个字节数组byte[]来做输入流的封装
- TFramedTransport: 同样使用非阻塞方式,按块的大小进行传输,输入流封装了 TMemoryInputTransport
Thrift服务类型(TServer)
Thrift服务类型分为阻塞和非阻塞式。
TSimpleServer
只有一个工作线程,循环监听传入的请求并进行处理,处理完成后才能接收下一个请求,是一种阻塞IO。效率较低。
TNonblockingServer
非阻塞IO实现IO多路复用,可以同时监听多个Socket。但业务处理仍然采用单线程,效率不高,多个请求仍然需要排队处理。
TThreadPoolServer
通过线程池进行处理,主线程只负责accept请求(监听Socket)。有新请求到来时,会拉起一个线程进行处理,效率较高。一旦并发量很大的时候(超过线程池数量),后面来的请求也只能排队等待。
TThreadedSelectorServer
内部有一个专门监听Socket的线程 + 多个处理线程 + 负载均衡线程(专门负责决定将Socket进行分配)。
参考文章
www.cnblogs.com/fingerboy/p… juejin.cn/post/684490… www.cnblogs.com/fingerboy/p…