深入了解Netty【五】线程模型

引言
不同的线程模型对程序的性能有很大的影响,Netty是建立在Reactor模型的基础上,要搞清Netty的线程模型,需要了解一目前常见线程模型的一些概念。
具体是进程还是线程,是和平台或者编程语言相关,本文为了描述方便,以线程描述。
目前存在的线程模型有:
- 传统阻塞IO服务模型
- Reactor模型
- Proactor模型
1、传统阻塞IO服务模型

采用阻塞IO模型获取输入的数据。 每个连接需要独立的完成数据的输入,业务的处理,数据返回。
当并发数大的时候,会创建大量的线程,占用系统资源,如果连接创建后,当前线程没有数据可读,会阻塞,造成线程资源浪费。
2、Reactor模型
IO多路复用 线程池 = Reactor模型

根据Reactor的数量和处理线程的数量,Reactor模型分为三类:
- 单Reactor单线程
- 单Reactor多线程
- 主从Reactor多线程
下面分别描述。
2.1、单Reactor单线程

图中:
- Reactor中的select模块就是IO多路复用模型中的选择器,可以通过一个阻塞对象监听多路连接请求。
- Reactor对象通过Select监控客户端请求事件,收到事件后,通过Dispatch进行分发。
- 如果是
建立连接事件,则用Acceptor通过Accept处理连接请求,然后创建一个Handler对象,处理连接完成后的业务处理。 - 如果不是建立连接事件,则Reactor会分发调用连接对应的Handler处理。
- Handler会处理Read-业务-Send流程。
这种模型,在客户端数量过多时,会无法支撑。因为只有一个线程,无法发挥多核CPU性能,且Handler处理某个连接的业务时,服务端无法处理其他连接事件。
以前在学习Redis原理的时候,发现它内部就是这种模型:深入了解Redis【十二】Reactor事件模型在Redis中的应用
2.2、单Reactor多线程

图中多线程体现在两个部分:
- Reactor主线程
Reactor通过select监听客户请求,如果是连接请求事件,则由Acceptor处理连接,如果是其他请求,则由dispatch找到对应的Handler,这里的Handler只负责响应事件,读取和响应,会将具体的业务处理交由Worker线程池处理。 - Worker线程池
Worker线程池会分配独立线程完成真正的业务,并将结果返回给Handler,Handler收到响应后,通过send将结果返回给客户端。
这里Reactor处理所有的事件监听和响应,高并发情景下容易出现性能瓶颈。
2.3、主从Reactor多线程

这种模式是对单Reactor的改进,由原来单Reactor改成了Reactor主线程与Reactor子线程。
- Reactor主线程的MainReactor对象通过select监听
连接事件,收到事件后,通过Acceptor处理连接事件。 - 当Acceptor处理完连接事件之后,MainReactor将连接分配给SubReactor。
- SubReactor将连接加入到连接队列进行监听,并创建handler进行事件处理。
- 当有新的事件发生时,SubReactor就会调用对应的handler处理。
- handler通过read读取数据,交由Worker线程池处理业务。
- Worker线程池分配线程处理完数据后,将结果返回给handler。
- handler收到返回的数据后,通过send将结果返回给客户端。
- MainReactor可以对应多个SubReactor。
这种优点多多,各个模块各司其职,缺点就是实现复杂。
3、Proactor模型

Proactor模型在理论上是比Reactor模型性能更好,但是因为依赖于操作系统的非阻塞异步模型,而linux的非阻塞异步模型还不完善,所以还是以Reactor为主。
总结
在学习这一部分知识的时候,想到redis中Reactor的应用,又想到了以前分析Tomcat源码时,其内部就是这种Reactor的思想。
突然感觉被我发现了一个天大的秘密:技术原理是通用的!
参考
Netty 系列之 Netty 线程模型
理解高性能网络模型

深入了解Netty【五】线程模型的更多相关文章
- Netty IO线程模型学习总结
Netty框架的 主要线程是IO线程.线程模型的好坏直接决定了系统的吞吐量.并发性和安全性. Netty的线程模型遵循了Reactor的基础线程模型.以下我们先一起看下该模型 Reactor线程模型 ...
- Netty Reactor 线程模型笔记
引用: https://www.cnblogs.com/TomSnail/p/6158249.html https://www.cnblogs.com/heavenhome/articles/6554 ...
- Netty服务器线程模型概览
一切从ServerBootstrap开始 ServerBootstrap负责初始话netty服务器,并且开始监听端口的socket请求. bootstrap bootstrap =newServerB ...
- netty之==线程模型
1.1 netty线程模型本质遵循了Reactor的基础线程模型,所以得先介绍Reactor模型 1.2 Reactor模型 无论是C++还是Java编写的网络框架,大多数都是基于Reactor模 ...
- 面试官:Netty的线程模型可不只是主从多Reactor这么简单
笔者看来Netty的内核主要包括如下图三个部分: 其各个核心模块主要的职责如下: 内存管理 主要提高高效的内存管理,包含内存分配,内存回收. 网通通道 复制网络通信,例如实现对NIO.OIO等底层JA ...
- netty reactor线程模型分析
netty4线程模型 ServerBootstrap http示例 // Configure the server. EventLoopGroup bossGroup = new EpollEvent ...
- Netty In Action中文版 - 第十五章:选择正确的线程模型
http://blog.csdn.net/abc_key/article/details/38419469 本章介绍 线程模型(thread-model) 事件循环(EventLoop) 并发(Con ...
- Netty线程模型
一.Reactor模型 1.单线程模型 Reactor单线程模型,指的是所有的IO操作都在同一个NIO线程上面完成,NIO线程的职责如下: 1)作为NIO服务端,接收客户端的TCP连接: 2)作为NI ...
- 【Netty源码分析】Reactor线程模型
1. 背景 1.1. Java线程模型的演进 1.1.1. 单线程 时间回到十几年前,那时主流的CPU都还是单核(除了商用高性能的小机),CPU的核心频率是机器最重要的指标之一. 在Java领域当时比 ...
随机推荐
- mPaaS 小程序架构解析 | 实操演示小程序如何实现多端开发
对于 mPaaS 小程序开发框架,想必读者们并不陌生.它源自于支付宝小程序框架,继承了易开发性.跨平台性及 Native 性能,不仅帮助开发者实现面向自有 App 投放小程序,还可快速构建打包,覆盖支 ...
- Java—构造方法及this/super/final/static关键字
构造方法 构建创造时用的方法,即就是对象创建时要执行的方法. //构造方法的格式: 修饰符 构造方法名(参数列表) { } 构造方法的体现: 构造方法没有返回值类型.也不需要写返回值.因为它是为构建对 ...
- pandas | 详解DataFrame中的apply与applymap方法
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是pandas数据处理专题的第5篇文章,我们来聊聊pandas的一些高级运算. 在上一篇文章当中,我们介绍了panads的一些计算方法, ...
- Vue Element-UI 中列表单选的实现
el-table中单选的实现 引用场景: 选择单条数据进行业务操作 实现方式: 给el-table-column设置el-radio Template 代码 <div class="r ...
- redis读写分离及可用性设计
Redis缓存架构设计 对于下面两个架构图,有如下想法: 1)redis主从复制模式,为了解决master读写压力,对master进行写操作,对slave进行读操作. 2)而在分片集群中,如果对部分分 ...
- 如何选择一台适合Java开发的电脑
前言 最近在群里有同学求推荐Java开发用的电脑,所以胖哥就出个简单的专题,用我贫瘠的电脑知识来帮助大家选择适合开发的电脑配置.因为家里的主机已经带不动两个 IDEA 了,更别提开个 Docker 啥 ...
- 为什么我们需要Logstash,Fluentd等日志摄取器?
前文传送门:Logging with ElasticSearch, Kibana, ASP.NET Core and Docker 疑问:既然应用能直接向ElasticSearch写日志,为什么我们还 ...
- Excel提取身份证年龄和性别③
问题场景 从user表中的身份信息中拿到用户的年龄和性别: 以下方法也可适用于提取其他数据,目的在于通过实例操作了解更多函数用法: 以下图中数据都为测试数据,不具备真实性! 场景一 从user表中的1 ...
- 第五篇 Scrum冲刺博客
一.会议图片 二.项目进展 成员 完成情况 今日任务 冯荣新 未完成 购物车列表,购物车工具栏 陈泽佳 未完成 静态结构 徐伟浩 商品信息录入 协助前端获取数据 谢佳余 未完成 搜索算法设计 邓帆涛 ...
- Ubuntu18.04 解决umount: /mnt: device is busy
通过该命令查看那个进程占用该device fuser -m /mnt 然后 kill -9 PID 最后就可以umount /mnt 了