李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
【转载】02.Netty线程模型
Leefs
2022-06-06 PM
864℃
0条
[TOC] ### 前言 接着我们学习一下 Netty 的线程模型,了解了 Netty 的线程模型之后我们对 Netty 的整体架构也就有了一个大致的了解。 由于 Netty 的线程模型是基于 Reactor 模型改进而来的,因此先讲讲 Reactor 模型,有助于我们对 Netty 线程模型的理解 。 ### 一、Reactor 模型 Reactor 模型是指当服务器接收到多个请求时,服务器程序会把它们分派到不同的方法或线程去处理。Reactor 模式也被称作 Dispatcher 模式。它的核心是多路复用器,多路复用器收到事件后会进行分发,这点是网络服务器高并发的关键。 **Reactor 模型分为三种:** + **单 Reactor 单线程** + **单 Reactor 多线程** + **多 Reactor 多线程** 这三种模型按顺序来看理解起来复杂度不断提升,也会更接近 Netty 的线程模型,下面来分别看看这三种模型。 #### 1.1 单 Reactor 单线程 这个最好理解,只有一个线程,只是会把建立连接和处理请求这两种任务分发给不同的类去处理,如下图所示: ![02.Netty线程模型01.png](https://lilinchao.com/usr/uploads/2022/06/699641470.png) 整个流程简单来讲就是 Reactor 通过 Selector 监听事件,收到事件使用 dispatch 对事件进行分发,如果是连接事件就由 Acceptor 进行处理,处理完成会创建一个 Handler 对后续业务进行处理。后面的数据请求都会由 Handler 进行处理。 **优点** + 模型简单,不会有多线程的那些问题 **缺点** - 性能问题:单线程无法发挥多核 CPU 的性能 - 可靠性问题:处理业务时往往容易出问题,当 Handler 出问题了,由于只有一个线程,整个节点也挂了 #### 1.2 单 Reactor 多线程 这个线程模型针对前面的问题作出了一定的优化,多出了处理业务的线程池,如下图所示: ![02.Netty线程模型02.png](https://lilinchao.com/usr/uploads/2022/06/2117845960.png) 前面的流程与单 Reactor 单线程是一致的,到 Handler 这一步就不一样了。这个模型 Handler 只负责读取数据和发送数据部分,业务处理交给了 Worker 线程,而 Worker 线程是由 Worker 线程池统一管理的。 **优点** - 可以充分利用多核 CPU 的处理能力 **缺点** - 多线程资源共享和访问处理会比较复杂,在主线程处理所有的连接、监听和响应也会出现性能瓶颈 #### 1.3 主从 Reactor 多线程 主从 Reactor 多线程模型又在前面的模型基础上做了进一步优化,增加了子 Reactor ,如下图所示: ![02.Netty线程模型03.png](https://lilinchao.com/usr/uploads/2022/06/2144514796.png) **整个流程大概可以分为以下几步**: + 主线程的 `MainReactor` 负责监听连接请求,收到连接请求会由 Acceptor 进行处理,成功建立连接之后 `MainReactor` 会把连接分派给 `SubReactor` ,由 `SubReactor` 监听和处理数据请求; + `SubReactor` 监听到数据请求,会派发给 Handler 处理,Handler 只会处理读取数据和发送数据部分,中间业务处理部分也是放在线程池中完成。 **优点** - `MainReactor` 与 `SubReactor` 职责分明,一个处理连接事件,一个处理数据请求; - `MainReactor` 与 `SubReactor` 交互逻辑比较简单,`MainReactor` 单向地将建立好的连接传递出去; - 多 Reactor 设计能在高并发场景拥有更好的性能。 **缺点** - 编程复杂度较高 主从 Reactor 多线程模式是业界非常成熟的服务器程序设计模式,在很多中间件中都使用到了这种模式,像 Nginx、Memcached、Netty 等。这种模式也被称为 1 + M + N 模式,分别代指相对少的连接线程(不一定为 1 ),多个 I/O 线程和多个业务处理线程。 ### 二、Netty 线程模型 Netty 线程模型是基于主从 Reactor 多线程模型优化而来的,整体架构如下图所示: ![02.Netty线程模型04.png](https://lilinchao.com/usr/uploads/2022/06/2100975846.png) Netty 的线程模型主要分为两部分,分别是 `BossGroup` 和 `WorkerGroup`,它们都分别管理一个或多个 `NioEventLoop`。每个 `NioEventLoop` 对应着一个线程,一个 Selector,一个 Executor 和一个 `TaskQueue`。 `NioEventLoop` 可以理解成一个事件循环,当程序启动后每个 `NioEventLoop` 都会通过 Executor 启动一个线程,开始执行事件循环,在循环中 Selector 会通过 select 方法阻塞并监听就绪事件,当有事件到来时通过 `processSeelectedKeys` 方法处理 Selector 事件,之后再通过 `runAllTasks` 方法处理其他的任务。 与前面介绍的 主从 Reactor 多线程模型类似,`BossGoup` 负责连接事件,当建立连接之后会生成一个 `NioSocketChannel` 并注册到 `WorkGroup` 其中一个 `NioEventLoop` 的 Selector 上。`WokerGroup` 中的 `NioEventLoop` 负责处理数据请求,当请求到来时会调用 `processSelectedKeys` 方法,其中的业务处理会依次经过 Pipeline 中的多个 Handler。 *附原文链接地址:* *https://anye3210.github.io/2021/08/22/%E5%A4%9A%E5%9B%BE%E8%AF%A6%E8%A7%A3-Netty/*
标签:
Netty
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:
https://www.lilinchao.com/archives/2136.html
上一篇
01.Netty概述
下一篇
03.Netty入门Demo
取消回复
评论啦~
提交评论
栏目分类
随笔
2
Java
326
大数据
229
工具
31
其它
25
GO
47
标签云
CentOS
锁
递归
Golang
Shiro
Git
LeetCode刷题
国产数据库改造
Jquery
哈希表
机器学习
数据结构和算法
前端
MyBatis-Plus
Spark Core
序列化和反序列化
Golang基础
Docker
Quartz
链表
Scala
Jenkins
NIO
Zookeeper
Tomcat
Yarn
线程池
Flink
Java阻塞队列
DataWarehouse
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞