Reactor线程模型以及在Netty中的应用

说道netty的线程模型,我们第一反应就是经典的Reactor线程模型,下面我们就来一起探讨一下三种经典的Reactor线程模型:

这里我们需要理解的一点是Reactor线程模型是基于同步非阻塞IO实现的。对于异步非阻塞IO的实现是Proactor模型。

本文主要包括

(1)Reactor单线程模型

(2)Reactor多线程模型

(3)主从Reactor多线程模型

(4)netty的多线程模型

1、Reactor单线程模型

Reactor单线程模型就是指所有的IO操作都在同一个NIO线程上面完成的,也就是IO处理线程是单线程的。NIO线程的职责是:

(1)作为NIO服务端,接收客户端的TCP连接;

(2)作为NIO客户端,向服务端发起TCP连接;

(3)读取通信对端的请求或者应答消息;

(4)向通信对端发送消息请求或者应答消息。

Reactor单线程模型图如下所示:

Reactor模式使用的是同步非阻塞IO(NIO),所有的IO操作都不会导致阻塞,理论上一个线程可以独立的处理所有的IO操作(selector会主动去轮询哪些IO操作就绪)。从架构层次看,一个NIO线程确实可以完成其承担的职责,比如上图的Acceptor类接收客户端的TCP请求消息,当链路建立成功之后,通过Dispatch将对应的ByteBuffer转发到指定的handler上,进行消息的处理。

对于一些小容量的应用场景下,可以使用单线程模型,但是对于高负载、大并发的应用场景却不适合,主要原因如下:

(1)一个NIO线程处理成千上万的链路,性能无法支撑,即使CPU的负荷达到100%;

(2)当NIO线程负载过重,处理性能就会变慢,导致大量客户端连接超时然后重发请求,导致更多堆积未处理的请求,成为性能瓶颈。

(3)可靠性低,只有一个NIO线程,万一线程假死或则进入死循环,就完全不可用了,这是不能接受的。

基于上诉问题,提出了Reactor的多线程模型:

2、Reactor多线程模型

Reactor多线程模型与单线程模型最大的区别在于,IO处理线程不再是一个线程,而是一组NIO处理线程。原理如下图所示:

Reactor多线程模型的特点如下:

(1)有一个专门的NIO线程—-Acceptor线程用于监听服务端,接收客户端的TCP连接请求。

(2)网络IO操作—-读写等操作由一个专门的线程池负责,线程池可以使用JDK标准的线程池实现,包含一个任务队列和N个可用的线程,这些NIO线程就负责读取、解码、编码、发送。

(3)一个NIO线程可以同时处理N个链路,但是一个链路只对应一个NIO线程。

Reactor多线程模型可以满足绝大多数的场景,除了一些个别的特殊场景:比如一个NIO线程负责处理客户所有的连接请求,但是如果连接请求中包含认证的需求(安全认证),在百万级别的场景下,就存在性能问题了,因为认证本身就要消耗CPU,为了解决这种情景下的性能问题,产生了第三种线程模型:Reactor主从线程模型。

3、主从Reactor多线程模型

主从Reactor线程模型的特点是:服务端用于接收客户端连接的不再是一个单独的NIO线程,而是一个独立的NIO的线程池。Acceptor接收到客户端TCP连接请求并处理完成后(可能包含接入认证),再将新创建的SocketChannel注册到IO线程池(sub reactor)的某个IO处理线程上并处理编解码和读写工作。Acceptor线程池仅负责客户端的连接与认证,一旦链路连接成功,就将链路注册到后端的sub Reactor的IO线程池中。 线程模型图如下:

利用主从Reactor模型可以解决服务端监听线程无法有效处理所有客户连接的性能不足问题,这也是netty推荐使用的线程模型。

4、Netty线程模型

netty的线程模型是可以通过设置启动类的参数来配置的,设置不同的启动参数,netty支持Reactor单线程模型、多线程模型和主从Reactor多线程模型。

服务端启动时创建了两个NioEventLoopGroup,一个是boss,一个是worker。实际上他们是两个独立的Reactor线程池,一个用于接收客户端的TCP连接,另一个用于处理Io相关的读写操作,或则执行系统的Task,定时Task。

Boss线程池职责如下:

(1)接收客户端的连接,初始化Channel参数

(2)将链路状态变更时间通知给ChannelPipeline

worker线程池作用是:

(1)异步读取通信对端的数据报,发送读事件到ChannelPipeline

(2)异步发送消息到通信对端,调用ChannelPipeline的消息发送接口

(3)执行系统调用Task;

(4)执行定时任务Task;

通过配置boss和worker线程池的线程个数以及是否共享线程池等方式,netty的线程模型可以在单线程、多线程、主从线程之间切换。

为了提升性能,netty在很多地方都进行了无锁设计。比如在IO线程内部进行串行操作,避免多线程竞争造成的性能问题。表面上似乎串行化设计似乎CPU利用率不高,但是通过调整NIO线程池的线程参数,可以同时启动多个串行化的线程并行运行,这种局部无锁串行线程设计性能更优。

nettyd的NioEventLoop读取到消息之后,直接调用ChannelPipeline的fireChannelRead(Object msg),只要用户不主动切换线程,一直都是由NioEventLoop调用用用户的Handler,期间不进行线程切换,这种串行化设计避免了多线程操作导致的锁竞争,性能角度看是最优的。

5、Netty的线程模型,设置最佳实践

(1)创建两个NioEventLoopGroup,隔离NIO Acceptor和NIO的IO线程。

(2)尽量不要在ChannelHandler中启动用户线程(解码之后,将POJO消息派发到后端的业务线程池除外)。

(3)解码要放在NIO线程调用的Handler中,不要放在用户线程中解码。

(4)如果IO操作非常简单,不涉及复杂的业务逻辑计算,没有可能导致阻塞的磁盘操作、数据库操作、网络操作等,可以再NIO线程调用的Handler中完成业务逻辑,不要切换到用户线程。

(5)如果IO业务操作比较复杂,就不要在NIO线程上完成,因为阻塞可能会导致NIO线程假死,严重降低性能。这时候可以把POJO封装成Task,派发到业务线程池中由业务线程处理,以保证NIO,线程被尽快的释放,处理其余的IO操作。

转载:http://blog.csdn.net/u010853261/article/details/55805216

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容