Thrift 个人实战--Thrift 网络服务模型(转)
前言:
  Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的rpc框架服务端/客户端代码. 不过Thrift的实现, 简单使用离实际生产环境还是有一定距离, 本系列将对Thrift作代码解读和框架扩充, 使得它更加贴近生产环境. 本文主要讲解Thrift的高性能网络框架模型, 讲解各种网络模型的特点和区别.
Thrift 高性能网络服务模型
1). TServer类层次体系
TSimpleServer/TThreadPoolServer是阻塞服务模型
TNonblockingServer/THsHaServer/TThreadedSelectotServer是非阻塞服务模型(NIO)
2). TServer抽象类的定义
内部静态类Args的定义, 用于TServer类用于串联软件栈(传输层, 协议层, 处理层)
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | publicabstractclassTServer {  publicstaticclassArgs extendsAbstractServerArgs<Args> {    publicArgs(TServerTransport transport) {      super(transport);    }  }  publicstaticabstractclassAbstractServerArgs<T extendsAbstractServerArgs<T>> {    publicAbstractServerArgs(TServerTransport transport);    publicT processorFactory(TProcessorFactory factory);    publicT processor(TProcessor processor);    publicT transportFactory(TTransportFactory factory);    publicT protocolFactory(TProtocolFactory factory);  }} | 
TServer类定义的抽象类
| 1 2 3 4 5 6 7 | publicabstractclassTServer {  publicabstractvoidserve();  publicvoidstop();  publicbooleanisServing();  publicvoidsetServerEventHandler(TServerEventHandler eventHandler);} | 
评注:
抽象函数serve由具体的TServer实例来实现, 而并非所有的服务都需要优雅的退出, 因此stop没有被定义为抽象
3). TSimpleServer
TSimpleServer实现, 正如其名Simple, 其实现非常的简单, 是个单线程阻塞模型, 只适合测试开发使用
抽象的代码可简单描述如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // *) server socket进行监听serverSocket.listen();while( isServing() ) {  // *) 接受socket链接  client = serverSocket.accept();  // *) 封装处理器  processor = factory.getProcess(client);  while( true) {    // *) 阻塞处理rpc的输入/输出    if( !processor.process(input, output) ) {      break;        }     }} | 
4). ThreadPoolServer
ThreadPoolServer解决了TSimple不支持并发和多连接的问题, 引入了线程池. 实现的模型是One Thread Per Connection
线程池代码片段:
| 1 2 3 4 5 6 7 8 9 | privatestaticExecutorService createDefaultExecutorService(Args args) {  SynchronousQueue<Runnable> executorQueue =    newSynchronousQueue<Runnable>();  returnnewThreadPoolExecutor(args.minWorkerThreads,                                args.maxWorkerThreads,                                60,                                TimeUnit.SECONDS,                                executorQueue);} | 
评注:
  采用同步队列(SynchronousQueue), 线程池采用能线程数可伸缩的模式.
主线程循环
| 1 2 3 4 5 6 7 8 9 | setServing(true);while(!stopped_) {  try{    TTransport client = serverTransport_.accept();    WorkerProcess wp = newWorkerProcess(client);    executorService_.execute(wp);  } catch(TTransportException ttx) {  }} | 
评注: 
  拆分了监听线程(accept)和处理客户端连接的工作线程(worker), 监听线程每接到一个客户端, 就投给线程池去处理. 这种模型能提高并发度, 但并发数取决于线程数, IO依旧阻塞, 从而限制该服务的服务能力.
5). TNonblockingServer
TNonblockingServer采用NIO的模式, 借助Channel/Selector机制, 采用IO事件模型来处理.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | privatevoidselect() {  try{    selector.select();  // wait for io events.    // process the io events we received    Iterator<SelectionKey> selectedKeys = selector.selectedKeys().iterator();    while(!stopped_ && selectedKeys.hasNext()) {      SelectionKey key = selectedKeys.next();      selectedKeys.remove();      if(key.isAcceptable()) {        handleAccept(); // deal with accept      } elseif(key.isReadable()) {        handleRead(key);    // deal with reads      } elseif(key.isWritable()) {        handleWrite(key); // deal with writes      }     }  } catch(IOException e) {  }} | 
评注:
select代码里对accept/read/write等IO事件进行监控和处理, 唯一可惜的这个单线程处理. 当遇到handler里有阻塞的操作时, 会导致整个服务被阻塞住.
6). THsHaServer
鉴于TNonblockingServer的缺点, THsHa引入了线程池去处理, 其模型把读写任务放到线程池去处理.
HsHa是: Half-sync/Half-async的处理模式, Half-aysnc是在处理IO事件上(accept/read/write io), Half-sync用于handler对rpc的同步处理上.
7). TThreadedSelectorServer
TThreadedSelectorServer是最成熟,也是被业界所推崇的RPC服务模型
TThreadedSelectorServer是对以上NonblockingServer的扩充, 其分离了Accept和Read/Write的Selector线程, 同时引入Worker工作线程池. 它也是种Half-sync/Half-async的服务模型.
总结:
MainReactor就是Accept线程, 用于监听客户端连接, SubReactor采用IO事件线程(多个), 主要负责对所有客户端的IO读写事件进行处理. 而Worker工作线程主要用于处理每个rpc请求的handler回调处理(这部分是同步的).
问题:
  这边提几个小小的问题, 考考读者?
  1). Java NIO中 Selector采用什么方式实现? c++中的select/poll/epool? 如果是epool的话, 采用的是水平触发,还是边缘触发?
  2). 这边非阻塞模型是HsHa, 有没有全异步的模式? 为何通用的模型是采用TThreadedSelectorServer这种模式呢?
  期待你的回答, 也敬请关注后续的文章.
Thrift 个人实战--Thrift 网络服务模型(转)的更多相关文章
- Thrift 个人实战--Thrift 网络服务模型
		前言: Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的rpc框架服务端/客户端代码. 不过Thrift的实现, 简单使用离实际生产环境还 ... 
- Thrift 个人实战--Thrift 的序列化机制
		前言: Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的rpc框架服务端/客户端代码. 不过Thrift的实现, 简单使用离实际生产环境还 ... 
- Thrift 个人实战--Thrift 服务化 Client的改造
		前言: Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的rpc框架服务端/客户端代码. 不过Thrift的实现, 简单使用离实际生产环境还 ... 
- Thrift 个人实战--Thrift RPC服务框架日志的优化
		前言: Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的rpc框架服务端/客户端代码. 不过Thrift的实现, 简单使用离实际生产环境还 ... 
- Thrift RPC实战(三) thrift序列化揭秘
		本文主要讲解Thrift的序列化机制, 看看thrift作为数据交换格式是如何工作的? 1.构造应用场景: 1). 首先我们先来定义下thrift的简单结构. 1 2 3 4 5 namespace ... 
- Thrift RPC实战(一).初次体验Thrift
		1.前言: Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的rpc框架服务端/客户端代码,主要特点: 开发速度快: 通过编写RPC接口ID ... 
- Thrift入门初探--thrift安装及java入门实例
		什么是thrift? 简单来说,是Facebook公布的一款开源跨语言的RPC框架. 那么问题来了. 什么是RPC框架? RPC全称为Remote Procedure Call,意为远程过程调用. 假 ... 
- 【thrift】thrift入门初探--thrift安装及java入门实例
		转载:https://www.cnblogs.com/fingerboy/p/6424248.html 公司的一些平台服务框架底层封装了thrift提供服务,最近项目不是很紧,于是研究了一下,刚刚入门 ... 
- Thrift架构~动态Thrift插件的注入
		先说AOP 说到注入,大家就会想起来IoC和AOP,确实如些,这一讲中,我们通过unity来实现对thrift插件的动态注入,事实上,这个功能在以后的项目中经常要用到,比如,你将一些功能分发到指定服务 ... 
随机推荐
- (转)不要自称是程序员,我十多年的 IT 职场总结
			其他: 我是一名程序员,工作很努力,为什么绩效还总是垫底? 外企,中年失业何去何从? 来公司半年了,也悟出了一些道理. 如果我可以给每个工程教育增加一门课,它不会涉及编译器.门电路或是时间复杂度,而是 ... 
- 测序中Q20 Q30 Q40
			你能给别人讲清楚这个概念吗? 二代测序中,每测一个碱基会给出一个相应的质量值,这个质量值是衡量测序准确度的.碱基的质量值13,错误率为5%,20的错误率为1%,30的错误率为0.1%.行业中Q20与Q ... 
- 第五章 [BX]和loop指令
			5.1 [bx] [bx]是什么 和 [0] 有些类似,[0] 表示内存单元,它的偏移地址是 0. 例如: mov ax, [0] 内存以字节为单位:ax以字(16bit = 2Byte)为单位:al ... 
- 20170711xlVBA批量制图一例
			Public Sub GatherDataPicker() Application.ScreenUpdating = False Application.DisplayAlerts = False A ... 
- Redis Commands(1)
			Redis 命令分为15类,如下: Cluster Connection Geo Hashes HyperLogLog Keys Lists Pub/Sub Scripting Server Sets ... 
- 想3分钟搭建图像识别系统?这里有一份TensorFlow速成教程(转)
			http://www.voidcn.com/article/p-wyaahqji-dr.html 从我们见到的各种图像识别软件来看,机器似乎能认出人脸.猫.狗.花草.各种汽车等等日常生活中出现的物体, ... 
- ansible-playbook快速入门填坑
			参考另外一篇文章 http://blog.51cto.com/weiweidefeng/1895261 when条件 参考http://blog.51cto.com/breezey/1757593 安 ... 
- Java网络编程和NIO详解8:浅析mmap和Direct Buffer
			Java网络编程与NIO详解8:浅析mmap和Direct Buffer 本系列文章首发于我的个人博客:https://h2pl.github.io/ 欢迎阅览我的CSDN专栏:Java网络编程和NI ... 
- 10个CSS简写/优化技巧-摘自网友
			10个CSS简写/优化技巧23来源/作者:未知 类别:前端开发 字体大小:大|中|小 背景颜色:蓝|白|灰 ? ? CSS简写就是指将多行的CSS属性简写成一行,又称为CSS代码优化或CSS缩写.CS ... 
- OC Foundation框架—字符串操作方法及习题
			#import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { ... 
