zoukankan      html  css  js  c++  java
  • Reactor IO模型

    Reactor的中心思想是将所有要处理的I/O事件注册到一个中心I/O多路复用器上,同时主线程/进程阻塞在多路复用器上;一旦有I/O事件到来或是准备就绪,多路复用器返回,并将事先注册的相应I/O事件分发到对应的处理器中

    相关概念介绍:

    • 事件:就是状态;比如:读就绪事件指的是我们可以从内核读取数据的状态
    • 事件分离器:一般会把事件的等待发生交给epoll、select;而事件的到来是随机,异步的,所以需要循环调用epoll,在框架里对应封装起来的模块就是事件分离器(简单理解为对epoll封装)
    • 事件处理器:事件发生后需要进程或线程去处理,这个处理者就是事件处理器,一般和事件分离器是不同的线程

    Reactor的一般流程

    • 1)应用程序在事件分离器注册读写就绪事件读写就绪事件处理器
    • 2)事件分离器等待读写就绪事件发生
    • 3)读写就绪事件发生,激活事件分离器,分离器调用读写就绪事件处理器
    • 4)事件处理器先从内核把数据读取到用户空间,然后再处理数据

    在Reactor线程模型的发展过程中,出现了不同的实现方式,具体有:

    • 单Reactor单线程

    • 单Reactor多线程

    • 主从Reactor多线程

     

    单Reactor 单线程 (Reactor和handler都在同一个线程中)

    方案说明:

    • Select是IO复用模型介绍的标准网络编程API,可以实现应用程序通过一个阻塞对象监听多路连接请求
    • Reactor对象通过Select监控客户端请求事件,收到事件后通过Dispatch进行分发
    • 如果是建立连接请求事件,则由Acceptor通过Accept处理连接请求,然后创建一个Handler对象处理连接完成后的后续业务
    • 如果不是建立连接事件,则Reactor会分发调用连接对应的Handler来处理业务
    • Handler会完成Read->业务处理->Send的完整业务流程


    c2bcdddaedfdcd364a71e1cb8d43eeb8.png

    这种模式的缺点在于:

    • 服务器端用一个线程通过多路复用搞定所有的IO操作,包括连接、读、写等,但是如果客户端连接数较多,将无法支撑,比如处理一个客户端的业务时,别的客户端的业务请求只能阻塞等待
    • 单线程无法发挥多核CPU的性能

    单Reactor + 多线程

    方案说明:

    • Reactor对象通过select监控客户端请求事件,收到事件后,通过dispatcher进行分发
    • 如果是建立连接的请求,则由Acceptor通过accept处理连接请求,然后创建一个Handler对象处理完成连接后的各种事件
    • 如果不是连接请求,则由Reactor分发调用连接对应的handler进行处理
    • handler只负责响应事件,不做具体的业务处理,通过read读取数据后,会分发给后面的worker线程池的某个线程处理业务
    • worker线程池会分发独立的线程完成真正的业务,并将结果返回给handler
    • handler收到响应的结果后,再通过send将结果返回给client


    03f594066eb6ecffeace5b2e299e16e6.png

    优点:

    • 多线程可以充分利用多核CPU的处理能力

    • 采用线程池复用线程,减少创建和销毁线程带来的性能开销

    缺点:

    • reactor处理所有事件的监听和响应,在单线程运行,高并发场景下容易出现性能瓶颈

    • 多线程数据共享和访问比较复杂

    主从Reactor + 多线程

    方案说明:

    • Reactor主线程MainReactor对象通过select监听连接事件,收到事件后,通过Acceptor处理连接事件
    • 当Acceptor处理连接事件后,MainReactor将连接分配给SubReactor
    • SubReactor将连接加入到连接队列进行监听,并创建handler进行各种事件处理
    • 当有新事件发生时,SubReactor就会调用对应的handler进行处理
    • handler通过Read读取数据,分发给后面的worker线程处理
    • worker线程池会分配独立的worker线程进行业务处理,并返回结果
    • handler收到响应的结果后,再通过send将结果返回给client
    • MainReactor主线程可以关联多个SubReactor子线程


    cda6b4b4126a944d0e5690b980479b66.png

    优点:

    • 主线程与子线程的数据交互简单职责明确,主线程只需要接收新连接,子线程完成后续的业务处理
    • 可以通过扩展多个Reactor子线程的方式来减小单个子线程的压力,提高并发处理能力

    Netty就是在主从Reactor多线程模型的基础上进行了一定的改进,同时,Kafka的网络架构设计也采用了这种主从Reactor多线程的模型。

    作者:潜行前行
    链接:https://juejin.cn/post/6892687008552976398
    来源:掘金
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 相关阅读:
    Python正课48 —— 匿名函数及其应用
    Python正课47 —— 面向过程编程思想
    Python正课46 —— 二分法
    Python正课45 —— 函数的递归调用
    Python正课44 —— 生成式
    Python正课43 —— 三元表达式
    SQL数据库操作命令大全
    css 高度写死 下滚动时ios 滚动不协调处理
    记录:js删除数组中某一项或几项的几种方法
    本次存储存数组对象
  • 原文地址:https://www.cnblogs.com/tonychanleader/p/15128357.html
Copyright © 2011-2022 走看看