一、Reactor三种线程模型

1.1、单线程模型

单个线程以非阻塞IO或事件IO处理所有IO事件,包括连接、读、写、异常、关闭等等。单线程Reactor模型基于同步事件分离器来分发事件,这个同步事件分离器,可以看做是一个单线程的while循环。下图描述了单线程模型的处理过程,看起来与网上大部分资料的图片不同,但本质是相同的。

注意上面的Selector之所以会有OP_ACEEPT事件,是因为在单线程模型中,Selector轮询的是监听套接字与已连接客户端套接字的所有IO事件。

单线程处理所有IO事件的弊端很明显。没能利用计算机CPU多核的特性,一个线程某个时刻只能处理单个IO事件,此时如果有其他描述符有IO事件就绪(如来了一个新的连接),这些IO事件将暂时得不到处理。

C++框架libevent中,基于event_base_loop做消息轮询,使用event_base_dispatch来分发IO消息,本质上是对上述模型的封装。如果不使用evthread_use_pthreads,则其默认就是单线程模型处理请求。

1.2、多线程模型

一个线程/进程接收连接、一组线程/进程处理IO读写事件。也就是将accept的线程与处理读、写等IO事件的线程分离,并且使用m多个线程以非阻塞IO或者事件IO来处理n个套接字的IO事件,这里的n一般远大于m,线程数m一般取CPU逻辑核心数的1-3倍,而套接字数n则取决于请求数和进程可以打开的最大描述符个数。下图是多线程模型

可以看到,这里把客户端的已连接套接字,转交给某个IO线程之后,由此线程轮询处理其之后的所有IO事件,这实际参考了netty4的线程模型设计。实际reactor的多线程模型,并不需要将已连接套接字绑定在某个线程上,也可以统一放在连接池中,由多个IOWork线程从池中取连接进行轮询并处理,但这样会复杂很多,而且容易出问题,比如说不同线程从同一个channel收到了write事件,这就类似惊群问题了;并且多线程并发操作同一个channel,后续很可能需要你将IO事件进行同步,与其如此,不如直接将channel绑定到一个线程,让channel上触发与处理IO事件逻辑上同步。netty3中channel(已连接套接字)入站事件由固定线程处理,出站事件由触发的线程处理,netty4中修改了设计,将channel绑定到固定的eventloop(线程)。

另外一点,每个已连接套接字的IO事件由固定线程处理,不代表事件也一定由此线程触发,恰恰相反,实际业务中,读(入站)事件来自于客户端写数据触发,而写(出站)事件往往由别的线程触发,例如在发起一个异步mysql操作完成之后,在异步回调线程中写结果数据来触发套接字的出站。

1.3、从多线程模型

一组线程/进程接收连接、一组线程/进程处理IO读写事件。它与多线程模型的主要区别在于其使用一组线程或进程在一个共享的监听套接字上accept连接。这么做的原因是为了应付单个线程/进程不足以快速处理内核中监听套接字的已连接套接字队列(并发量极大)的情况。如下: 

主从多线程模型,有可能引起惊群效应。不过这个问题已经渐渐被规避,内核可以保证连接只被唯一一个accept调用所获取,其余对此连接的accept调用将失败。

二、Netty支持的线程模型

Netty支持单线程、多线程模型、主从多线程模型。但经本人多次测试、调试发现,ServerBootstrap默认不会使用主从多线程模型。虽然server支持设置EventLoopGroup(多个EventLoop)。但实际对于一个本地地址(IP+端口)进行accept,netty只会绑定到一个EventLoop上,故只会创建一个线程处理。

按本人的理解,Boss EventLoopGroup(Master EventLoopGroup,参数nThreads不为1)的作用主要用在对共享的监听套接字或者多个本地地址监听,对多个本地地址进行监听一般表示一个JVM中有多个server,即有多个ServerBootStrap,这时,Boss EventLoopGroup可以通过共享给这多个ServerBootStrap起到作用(创建多个boss/master Thread)。

以下面的代码为例MASTER_THREAD_CNT为4,但netty实际只会使用第一个EventLoop,只会给第一个EventLoop创建线程。

调试跟踪源码,可以明白netty的逻辑。
在ServerBootstrap继承的initAndRegister方法中,调用MultithreadEventLoopGroup#register方法,此方法调用this.next获取当前索引的下一个(索引位0,即是第一个)EventLoop。

然后register方法进一步调用register方法,在register中执行eventLoop.execute,这里才会真正为监听套接字创建第一个轮询线程。

问题就在于在ServerBootstrap上调用bind方法,初始化监听socket并绑定EventLoop时,是调用的next方法。因此netty只会初始化第一个MasterEventLoop,如果想将MasterEventLoopGroup中的每个EventLoop都初始化,很显然,需要重复绑定多个监听套接字或者多次绑定一个可共享的套接字。

Reactor三种线程模型与Netty线程模型相关推荐

  1. reactor线程模型_简单了解Java Netty Reactor三种线程模型

    1. Reactor三种线程模型 1.1. 单线程模型 Reactor单线程模型,指的是所有的IO操作都在同一个NIO线程上面完成,NIO线程的职责如下: 1)作为NIO服务端,接收客户端的TCP连接 ...

  2. IO模型及Netty线程模型

    Netty简介 1. 简介 版本:Netty4.X Netty是基于NIO的异步网络通信框架 能快速的搭建高性能易扩展的网络应用程序(服务器/客户端) 2. 特征 设计 适用于各种传输类型的统一API ...

  3. 线程池三种创建方式和自定义线程池ThreadPoolExecutor

    线程池的优势: 线程池做的工作只要是控制运行的线程数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果线程数量超过了最大数量,超出数量的线程排队等候,等其他线程执行完毕,再从队列中取出任 ...

  4. java线程三种方法,Java基础_线程的使用及创建线程的三种方法

    线程:线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务. 进程:进 ...

  5. Java开发中Netty线程模型原理解析!

    Java开发中Netty线程模型原理解析,Netty是Java领域有名的开源网络库具有高性能和高扩展性的特点,很多流行的框架都是基于它来构建.Netty 线程模型不是一成不变的,取决于用户的启动参数配 ...

  6. Java创建线程的三种方法

    这里不会贴代码,只是将创建线程的三种方法做个笼统的介绍,再根据源码添加上自己的分析. 通过三种方法可以创建java线程: 1.继承Thread类. 2.实现Runnable接口. 3.实现Callab ...

  7. java 反应堆模式_Netty中的三种Reactor(反应堆)

    目录: Reactor(反应堆)和Proactor(前摄器) <Java NIO系列教程(八)JDK AIO编程>-- java AIO的proactor模式 Netty的I/O线程Nio ...

  8. java中reactor模型_Java——Netty Reactor模型(转)

    1. Reactor三种线程模型 1.1. 单线程模型 Reactor单线程模型,指的是所有的IO操作都在同一个NIO线程上面完成,NIO线程的职责如下: 1)作为NIO服务端,接收客户端的TCP连接 ...

  9. 独家 | 将时间信息编码用于机器学习模型的三种编码时间信息作为特征的三种方法...

    作者:Eryk Lewinson 翻译:汪桉旭 校对:zrx本文约4400字,建议阅读5分钟 本文研究了三种使用日期相关的信息如何创造有意义特征的方法. 标签:时间帧,机器学习,Python,技术演示 ...

最新文章

  1. 从数仓到数据中台,谈技术选型最优解
  2. Android wear
  3. 关于华为x2中的外置SDCard的使用
  4. 【Python】PAT-1024-科学计数法
  5. 动态规划-重叠区间2020.3.30
  6. iOS开发之邮件发送代码
  7. 计算机应用124单元测试卷,《计算机应用基础》第一部分单元测试试卷
  8. AS3 调用外部SWF中元件库中的元件 【转】
  9. python 元组遍历_Python中的for循环:元组、列表、字典的遍历和相互转化
  10. 进程之间通信 共享内存
  11. 团队协助 开源项目_5分钟了解 Vtiger CRM-国际知名开源客户管理软件
  12. Mac解压Windows 压缩文件(.zip格式)乱码问题
  13. 设计模式 代理模式(Proxy Pattern)
  14. python怎么样算安装好了_如何将安装好的Python
  15. Max and Min---递归
  16. WS2811芯片 SM16703 SOP8 RGB流水幻彩灯LED驱动IC
  17. 一款开源的微信小程序商城项目,接外包直接拿去改改,就能用。。。
  18. Android API统计
  19. 我的MBTI 职业性格分析报告——ISFP型
  20. [SCOI2014]方伯伯的玉米田

热门文章

  1. C语言宏定义取得两数的最大值和最小值
  2. 和吴昊一起玩推理 Round 2 —— 蚂蚁爬杆问题
  3. C++ 下一代标准库 tr1中默认的哈希 FNV hash
  4. 使用ASP.net 2.0 的一些新特性
  5. pthread_join()函数理解
  6. UDT源码剖析(六):UDT::socket()过程代码注释
  7. ubuntu start
  8. 每日一题(35)—— heap与stack的差别
  9. C++ —— 初识C++
  10. sx1268 中文_STM32开发笔记85: SX1268驱动程序设计(芯片唤醒)