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


引言

不一样的线程模型对程序的性能有很大的影响,Netty是创建在Reactor模型的基础上,要搞清Netty的线程模型,须要了解一目前常见线程模型的一些概念。 具体是进程仍是线程,是和平台或者编程语言相关,本文为了描述方便,以线程描述。 目前存在的线程模型有:linux

  • 传统阻塞IO服务模型
  • Reactor模型
  • Proactor模型

一、传统阻塞IO服务模型

传统阻塞IO服务模型.png

采用阻塞IO模型获取输入的数据。 每一个链接须要独立的完成数据的输入,业务的处理,数据返回。 当并发数大的时候,会建立大量的线程,占用系统资源,若是链接建立后,当前线程没有数据可读,会阻塞,形成线程资源浪费。redis

二、Reactor模型

IO多路复用 线程池 = Reactor模型 Reactor.png编程

根据Reactor的数量和处理线程的数量,Reactor模型分为三类:网络

  • 单Reactor单线程
  • 单Reactor多线程
  • 主从Reactor多线程

下面分别描述。多线程

2.一、单Reactor单线程

单Reactor单线程.png 图中:并发

  • Reactor中的select模块就是IO多路复用模型中的选择器,能够经过一个阻塞对象监听多路链接请求。
  • Reactor对象经过Select监控客户端请求事件,收到事件后,经过Dispatch进行分发。
  • 若是是创建链接事件,则用Acceptor经过Accept处理链接请求,而后建立一个Handler对象,处理链接完成后的业务处理。
  • 若是不是创建链接事件,则Reactor会分发调用链接对应的Handler处理。
  • Handler会处理Read-业务-Send流程。

这种模型,在客户端数量过多时,会没法支撑。由于只有一个线程,没法发挥多核CPU性能,且Handler处理某个链接的业务时,服务端没法处理其余链接事件。 之前在学习Redis原理的时候,发现它内部就是这种模型:深刻了解Redis【十二】Reactor事件模型在Redis中的应用异步

2.二、单Reactor多线程

单Reactor多线程.png

图中多线程体如今两个部分:编程语言

  • Reactor主线程 Reactor经过select监听客户请求,若是是链接请求事件,则由Acceptor处理链接,若是是其余请求,则由dispatch找到对应的Handler,这里的Handler只负责响应事件,读取和响应,会将具体的业务处理交由Worker线程池处理。
  • Worker线程池 Worker线程池会分配独立线程完成真正的业务,并将结果返回给Handler,Handler收到响应后,经过send将结果返回给客户端。

这里Reactor处理全部的事件监听和响应,高并发情景下容易出现性能瓶颈。高并发

2.三、主从Reactor多线程

主从Reactor多线程.png

这种模式是对单Reactor的改进,由原来单Reactor改为了Reactor主线程与Reactor子线程。post

  • Reactor主线程的MainReactor对象经过select监听链接事件,收到事件后,经过Acceptor处理链接事件。
  • 当Acceptor处理完链接事件以后,MainReactor将链接分配给SubReactor。
  • SubReactor将链接加入到链接队列进行监听,并建立handler进行事件处理。
  • 当有新的事件发生时,SubReactor就会调用对应的handler处理。
  • handler经过read读取数据,交由Worker线程池处理业务。
  • Worker线程池分配线程处理完数据后,将结果返回给handler。
  • handler收到返回的数据后,经过send将结果返回给客户端。
  • MainReactor能够对应多个SubReactor。

这种优势多多,各个模块各司其职,缺点就是实现复杂。

三、Proactor模型

Proactor.png

Proactor模型在理论上是比Reactor模型性能更好,可是由于依赖于操做系统的非阻塞异步模型,而linux的非阻塞异步模型还不完善,因此仍是以Reactor为主。

总结

在学习这一部分知识的时候,想到redis中Reactor的应用,又想到了之前分析Tomcat源码时,其内部就是这种Reactor的思想。 忽然感受被我发现了一个天大的秘密:技术原理是通用的!

参考

Netty 系列之 Netty 线程模型 理解高性能网络模型

tencent.jpg

相关文章
相关标签/搜索