文档章节

Thrift源码分析--TThreadedSelectorServer线程模型

輕風
 輕風
发布于 2017/03/17 21:17
字数 700
阅读 469
收藏 16

Thrift的网路服务模型之一的 TThreadedSelectorServer 实现了多Reactor线程模型,请先理解线程模型再深入分析源码。线程模型的讲解此处不再赘述,给出一张总结图如下:

TThreadedSelectorServer线程模型

截图来自:Thrift 服务模型和序列化机制深入学习

下面从一次完整的服务调用过程来分析源码:

1. 服务入口

先来看看服务入口函数 serve() ,TThreadedSelectorServer 的 serve() 方法继承自 AbstractNoblockingServer 抽象类。

serve()

其中startThread() 方法为抽象方法,在 TThreadedSelectorServer 中实现如下:

startThread()

在 startThread() 方法中启动了一个 AcceptThread(用来接收网络socket)和多个 SelectorThread(进行网络I/O操作)。接下来具体分析这两个线程对象。

2. Acceptor

直接看其 run() 方法可知,内部不断的循环监听新来的网络连接:

AcceptThread.run()

将就绪的连接分配到对应 SelectorThread 中的 BlockingQueue 队列中:

doAddAccept

在 handleAccept() 方法中使用了 SelectorThreadLoadBalancer 负载均衡器轮循分发就绪的连接到对应的 SelectorThread 上去:

handleAccept()

SelectorThreadLoadBalancer

接下来看 Selector 如何处理连接。

3. Selector

同样线程对象直接看其 run() 方法:可以看到待网络 I/O 事件发生时处理对应的 I/O 事件。

Selector.run()

深入对应读写方法可以发现,真正数据的读写操作是调用 FrameBuffer 的 read()/write() 方法,后续我们再对 FrameBuffer 类做讲解,接下来看下工作线程池部分的实现。

4. 任务工作线程池

使用的是Java 提供的 ExecutorService 线程池来管理工作线程。线程池配置来至 Args 配置管理类中:

工作线程池

默认实现是 FixedThreadPool 大小为 5,可以自定义调节大小和修改线程池实现。

接下来我们根据其调用处来跟进线程池的用出:

使用处一:Acceptor中的 handleAccept 方法用来处理 FAIR_ACCEPT 策略的新连接。

handleAccept

使用处二:当SelectorThread 完成 read 操作后,回调 frameBuffer.invoke() 方法 -- 最后回调业务处理方法。

handleRead

从线程池中取出线程去执行 Invocation 线程对象:

requestInvoke

Invocation 封装 FrameBuffer 的 invoke() 方法到单独的线程中。

Invocation

FrameBuffer 中的 invoke() 方法:

invoke()

从图中可以看到回调 TProcessor 接口的 process(in, out) 方法。 Thrift IDL 生成代码中的 Processor 类实现 TProcessor 接口,Processor 中对应的业务方法实际是调用 Iface 接口定义的业务方法,我们自己的业务代码实现 Iface 接口完成自己的业务处理逻辑。

TProcessor

完成业务逻辑处理后,会调用 responseReady() 方法,其内部判断数据读取完成和业务处理完成后,将更改 FrameBufferState 为 write 状态,然后开始回写结果给调用端。

至此完成一次完整的服务调用过程。

© 著作权归作者所有

輕風
粉丝 4
博文 2
码字总数 1601
作品 0
朝阳
程序员
私信 提问
Thrift源码分析1-server

前言 Thrift是由FB开发的rpc框架,后贡献到apache成为开源项目,thrift可以支持多种语言,如 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk 等,本系列文章主...

Small-Liu
2016/02/02
859
0
Thrift 指导文档 [0.9.2]

0 前言 Thrift 是一个软件框架(远程过程调用框架),用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引 擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, ...

强子哥哥
2015/08/23
705
0
(转)Java版的各种Thrift server实现的比较

本文是我对这篇文章的翻译:Thrift Java Servers Compared,为了便于阅读,我将原文附于此处,翻译穿插在其中。此外,为了防止原链接在未来某一天失效后,文中的图片再也看不到的问题,我将原...

Mr_Tea
2016/07/11
104
0
跨语言RPC框架Thrift详解

Thrift的传输格式(协议层) Thrift之所以被称为一种高效的RPC框架,其中一个重要的原因就是它提供了高效的数据传输。 以下是Thrift的传输格式种类: TBinaryProtocol: 二进制格式。效率显然...

dragon_tech
01/07
117
0
RPC框架之Thrift分析

一、简介 1、Thrift是Facebook开发的跨语言的RPC服务框架。随后贡献给Apache开源组织。成为RPC服务的主流框架。 2、特点: 优点: 跨语言,支持java、c/c++、python等多种编程语言 IDL定义接...

caiz
2016/04/28
2.2K
0

没有更多内容

加载失败,请刷新页面

加载更多

Mybatis Plus删除

/** @author beth @data 2019-10-17 00:30 */ @RunWith(SpringRunner.class) @SpringBootTest public class DeleteTest { @Autowired private UserInfoMapper userInfoMapper; /** 根据id删除......

一个yuanbeth
今天
4
0
总结

一、设计模式 简单工厂:一个简单而且比较杂的工厂,可以创建任何对象给你 复杂工厂:先创建一种基础类型的工厂接口,然后各自集成实现这个接口,但是每个工厂都是这个基础类的扩展分类,spr...

BobwithB
今天
4
0
java内存模型

前言 Java作为一种面向对象的,跨平台语言,其对象、内存等一直是比较难的知识点。而且很多概念的名称看起来又那么相似,很多人会傻傻分不清楚。比如本文我们要讨论的JVM内存结构、Java内存模...

ls_cherish
今天
4
0
友元函数强制转换

友元函数强制转换 p522

天王盖地虎626
昨天
5
0
js中实现页面跳转(返回前一页、后一页)

本文转载于:专业的前端网站➸js中实现页面跳转(返回前一页、后一页) 一:JS 重载页面,本地刷新,返回上一页 复制代码代码如下: <a href="javascript:history.go(-1)">返回上一页</a> <a h...

前端老手
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部