Thrift 个人实战--Thrift 网络服务模型
前言:
Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的rpc框架服务端/客户端代码. 不过Thrift的实现, 简单使用离实际生产环境还是有一定距离, 本系列将对Thrift作代码解读和框架扩充, 使得它更加贴近生产环境. 本文主要讲解Thrift的高性能网络框架模型, 讲解各种网络模型的特点和区别.
Thrift 高性能网络服务模型
1). TServer类层次体系
TSimpleServer/TThreadPoolServer是阻塞服务模型
TNonblockingServer/THsHaServer/TThreadedSelectotServer是非阻塞服务模型(NIO)
2). TServer抽象类的定义
内部静态类Args的定义, 用于TServer类用于串联软件栈(传输层, 协议层, 处理层)
public abstract class TServer {
public static class Args extends AbstractServerArgs<Args> {
public Args(TServerTransport transport) {
super(transport);
}
}
public static abstract class AbstractServerArgs<T extends AbstractServerArgs<T>> {
public AbstractServerArgs(TServerTransport transport);
public T processorFactory(TProcessorFactory factory);
public T processor(TProcessor processor);
public T transportFactory(TTransportFactory factory);
public T protocolFactory(TProtocolFactory factory);
}
}
TServer类定义的抽象类
public abstract class TServer {
public abstract void serve();
public void stop();
public boolean isServing();
public void setServerEventHandler(TServerEventHandler eventHandler);
}
评注:
抽象函数serve由具体的TServer实例来实现, 而并非所有的服务都需要优雅的退出, 因此stop没有被定义为抽象
3). TSimpleServer
TSimpleServer实现, 正如其名Simple, 其实现非常的简单, 是个单线程阻塞模型, 只适合测试开发使用
抽象的代码可简单描述如下:
// *) 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
线程池代码片段:
private static ExecutorService createDefaultExecutorService(Args args) {
SynchronousQueue<Runnable> executorQueue =
new SynchronousQueue<Runnable>();
return new ThreadPoolExecutor(args.minWorkerThreads,
args.maxWorkerThreads,
60,
TimeUnit.SECONDS,
executorQueue);
}
评注:
采用同步队列(SynchronousQueue), 线程池采用能线程数可伸缩的模式.
主线程循环
setServing(true);
while (!stopped_) {
try {
TTransport client = serverTransport_.accept();
WorkerProcess wp = new WorkerProcess(client);
executorService_.execute(wp);
} catch (TTransportException ttx) {
}
}
评注:
拆分了监听线程(accept)和处理客户端连接的工作线程(worker), 监听线程每接到一个客户端, 就投给线程池去处理. 这种模型能提高并发度, 但并发数取决于线程数, IO依旧阻塞, 从而限制该服务的服务能力.
5). TNonblockingServer
TNonblockingServer采用NIO的模式, 借助Channel/Selector机制, 采用IO事件模型来处理.
private void select() {
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
} else if (key.isReadable()) {
handleRead(key); // deal with reads
} else if (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插件的动态注入,事实上,这个功能在以后的项目中经常要用到,比如,你将一些功能分发到指定服务 ...
随机推荐
- 【转】CentOS下载版本介绍
官网:http://www.centos.org/ 下载:http://mirror.neu.edu.cn/centos/6.6/isos/ 系统运维:http://www.osyunwei.com/ ...
- O(1) Check Power of 2 - LintCode
examination questions Using O(1) time to check whether an integer n is a power of 2. Example For n=4 ...
- Vector成员为指针时要注意的问题
vector的复制是浅复制,所以复制一个包含动态内存的变量的对象的话就会出问题. 解决办法:自己写类的复制构造函数,为新对象的指针开辟新的内存空间. 但当vector离开作用域之后,只会把其成员所占的 ...
- 基于gulp 的前端自动化构建方案总结
一,基础篇 先安装nodejs 使用淘宝镜像安装tnpm 安装 cnpm 插件:npm install -g cnpm --registry=https://registry.npm.taobao.o ...
- kafka原理存储
http://www.open-open.com/lib/view/open1421150566328.html
- Oracle存储过程-自定义数据类型,集合,遍历取值
摘要 Oracle存储过程,自定义数据类型,集合,遍历取值 目录[-] 0.前言 1.Packages 2.Packages bodies 3.输出结果 0.前言 在Oracle的存储过程中,可能会遇 ...
- 使用 GPG 对数据进行加密解密签名
一:使用 GPG 对数据进行加密解密签名 基本的工具使用 1. GPG 是GNUPG 免费开源的gpg加密工具,和同pgp兼容,pgp收费. 2. 在mac上使用https://gpgtools.or ...
- SPSS数据分析—描述性统计分析
描述性统计分析是针对数据本身而言,用统计学指标描述其特征的分析方法,这种描述看似简单,实际上却是很多高级分析的基础工作,很多高级分析方法对于数据都有一定的假设和适用条件,这些都可以通过描述性统计分析加 ...
- C++ template的一些高级用法(元编码,可变参数,仿函数,using使用方法,. C++ 智能指针)
1 . 通用函数可变参数模板 对于有些时候,我们无法确切的知道,函数的参数个数时,而又不想过多的使用所谓的函数重载,那么就可以效仿下面的例子: #include<iostream> #i ...
- NetworkComms V3 之同时监听多端口
NetworkComms网络通信框架序言 NetworkComms通信框架,是一款来自英国的c#语言编写的通信框架,历时6年研发,成熟稳定,性能可靠. 框架支持同时监听服务器上的多个端口,写法如下 ...