【thrift】 thrift原理浅析
上文介绍了 thrift 入门例子
下面简单介绍 thrift 的基本原理
这里以 thrift server端为例子
1.创建socket
/*
* thrift 封装的 socket 层,使用端口7911构建一个非阻塞的socket
*/
TNonblockingServerTransport serverTransport =
new
TNonblockingServerSocket(7911);
server端创建的socket ,这是非阻塞的serversocket,使用的将是nio
看下源码:
TNonblockingServerSocket 构造方法最终会调用下面的构造方法
public
TNonblockingServerSocket(InetSocketAddress bindAddr,
int
clientTimeout)
throws
TTransportException {
clientTimeout_
= clientTimeout;
try
{
serverSocketChannel
= ServerSocketChannel. open();
serverSocketChannel
.configureBlocking(
false
);
// Make server socket
serverSocket_
=
serverSocketChannel
.socket();
// Prevent 2MSL delay problem on server restarts
serverSocket_
.setReuseAddress(
true
);
// Bind to listening port
serverSocket_
.bind(bindAddr);
}
catch
(IOException ioe) {
serverSocket_
=
null
;
throw
new
TTransportException(
"Could not create ServerSocket on address "
+ bindAddr.toString() +
"."
);
}
}
构造方法包含的内容很明显,就是创建一个serversocket,并绑定到指定的端口
2.创建输入输出流协议对象
/*
* thrift 协议层,这里使用的是 二进制协议
*/
Factory proFactory =
new
TBinaryProtocol.Factory();
抽取其中部分代码,如下,
TBinaryProtocol 对象定义了数据序列化和反序列化的操作
private
byte
[]
i32out
=
new
byte
[4];
public
void
writeI32(
int
i32)
throws
TException {
i32out
[0] = (
byte
)(0xff & (i32 >> 24));
i32out
[1] = (
byte
)(0xff & (i32 >> 16));
i32out
[2] = (
byte
)(0xff & (i32 >> 8));
i32out
[3] = (
byte
)(0xff & (i32));
trans_
.write(
i32out
, 0, 4);
}
private
byte
[]
i32rd
=
new
byte
[4];
public
int
readI32()
throws
TException {
byte
[] buf =
i32rd
;
int
off = 0;
if
(
trans_
.getBytesRemainingInBuffer() >= 4) {
buf =
trans_
.getBuffer();
off =
trans_
.getBufferPosition();
trans_
.consumeBuffer(4);
}
else
{
readAll(
i32rd
, 0, 4);
}
return
((buf[off] & 0xff) << 24) |
((buf[off+1] & 0xff) << 16) |
((buf[off+2] & 0xff) << 8) |
((buf[off+3] & 0xff));
}
3.数据
读写
及
处理
/*
* thrift idl接口的实现类
*/
HelloServiceImpl testimpl =
new
HelloServiceImpl();
/*
* thrift Processor 业务逻辑处理层
*/
TProcessor processor =
new
HelloService.Processor<HelloServiceImpl>(testimpl);
定义我们Service的实现类
HelloServiceImpl
创建Processor,
HelloServiceImpl
实现类作为参数传入Processor构造方法里
processor主要完成的事情:
1.把idl里定义的方法进行封装,最终暴露出一个统一的接口给thrift server进行调用
2.封装protocol和transport层,包括输入输出流的处理细节、序列化反序列化
看下thrift 生成的 HelloService 里的 Processor 类:
processor类继承
TBaseProcessor
public
static
class
Processor<I
extends
Iface>
extends
org.apache.thrift.TBaseProcessor<I>
implements
org.apache.thrift.TProcessor {
private
static
final
Logger
LOGGER
= LoggerFactory.getLogger(Processor.
class
.getName());
// Processor的构造方法
// getProcessMap 里把我们定义的方法 helloWorld 封装成对象并设置到map里
public
Processor(I iface) {
super
(iface, getProcessMap(
new
HashMap<String, org.apache.thrift.ProcessFunction<I, ?
extends
org.apache.thrift.TBase>>()));
}
protected
Processor(I iface, Map<String, org.apache.thrift.ProcessFunction<I, ?
extends
org.apache.thrift.TBase>> processMap) {
super
(iface, getProcessMap(processMap));
}
private
static
<I
extends