多线程Reactor分析,从性能,客户接入量方向

简介: 多线程Reactor分析,从性能,客户接入量方向

前言

  • 前文精彩回顾,基于epoll封装一个简单的reactor反应堆模式, 事件循环

一. 为什么要使用Reactor设计模式

缺点1:   每一个connect 都对应一个线程,线程占用系统资源,并发数过大时,系统资源不足以支撑.      (系统资源上限制并发量)

缺点2:    阻塞IO,在等待IO到来的时候会阻塞住线程,阻塞占用线程, 线程利用率低下,且线程数量有限,是对资源的一种极大的浪费   (占着线程不工作)


解决阻塞IO + 多线程资源浪费   --- Reactor模型


基于池化思想,避免为每个连接创建线程,连接完成后将业务处理交给线程池处理. (开启work_threads线程池处理业务需求)     ---  实现网络IO  跟   业务处理的解耦合 同时避免为每一个连接创建线程


基于IO复用技术,多个连接阻塞在同一个对象上,多个连接中出现IO事件的触发,操作系统就会通知应用程序处理                       ---  还是阻塞, 但是是多个IO阻塞在一个对象上,  所以多路:就是多个IO,复用 :复用一个线程


理解IO复用:对比一下普通阻塞IO: 一个IO事件单独阻塞一个线程,     多路IO复用: 多个IO事件共同阻塞一个线程                            ---   将多个IO阻塞等待 重合阻塞在一起。提高线程利用率.


Reactor   :  集合IO复用 + 线程池 思想.      IO驱动---> 事件驱动  (事件循环)

二.Reactor线程模型分类

根据Reactor的数量和处理资源的线程数量的不同,分为三类:

  • 单Reactor单线程模型

在一个Reactor中完成所有事情, IO事件注册,IO事件分发  IO事件处理   --- 单个线程中实现

缺陷:


单个线程处理所有请求, 对于多核CPU着实是一种浪费


当处理读写任务的线程负载过高后,处理速度下降,事件会堆积,严重的会超时,可能导致客户端重新发送请求,性能越来越差    

不能支持高接入量,  服务器的接入量低,  因为在 accept 建立连接的请求中夹杂了大量的业务处理,业务处理耗时长, 造成accept占比低下,能同时支持的用户接入量低下

典型代表实例:redis 内存数据库 操作redis当中的数据结构

  • 单Reactor多线程模型

和单Reactor单线程相比核心在于将业务逻辑从Reactor中剥离出来放入work_threads中进行处理,实现网络IO  和 业务处理之间的解耦合。 充分利用多核资源,提高性能, 提高了用户接入量和可靠性

缺陷:

Reactor线程承担所有的事件,既要处理新连接的建立,又要处理read, send IO事件, 高并发场景下单线程存在性能问题,并且对于高接入量场景下无法及时响应大量的acceptor.

代表:skynet

  • 多Reactor多线程模型

这种模型下和第二种模型相比是把Reactor线程拆分了mainReactor和subReactor两个部分,mainReactor只处理连接事件,读写事件交给subReactor来处理。业务逻辑还是由线程池来处理.

mainRactor只处理连接事件,用一个线程来处理就好。处理读写事件的subReactor个数一般和CPU数量相等,一个subReactor对应一个线程,业务逻辑由线程池处理  (单独的main线程 mainReactor 专门处理连接,  可以大大的提高接入量 )   可靠性大大提高


这种模型使各个模块职责单一,降低耦合度,性能和稳定性都有提高


这种模型在许多项目中广泛应用,比如Netty的主从线程模型 memcached 等

三.Reactor线程模型生活化

餐厅一般有接待员和服务员,接待员负责在门口接待顾客,服务员负责全程服务顾客


Reactor的三种线程模型可以用接待员和服务员类比


单Reactor单线程模型:接待员和服务员是同一个人,一直为顾客服务。客流量较少适合


单Reactor多线程模型:一个接待员,多个服务员。客流量大,一个人忙不过来,由专门的接待员在门口接待顾客,然后安排好桌子后,由一个服务员一直服务,一般每个服务员负责一片中的几张桌子


多Reactor多线程模型:多个接待员,多个服务员。这种就是客流量太大了,一个接待员忙不过来了

四. 总结本章

    本章从为传统的并发服务器:多线程阻塞IO 的弊端入手引出来为什么需要Reactor模式


    多线程阻塞IO  :  主要弊端是:可以创建的线程量有限     ---  并发量限制


    阻塞IO : 阻塞线程,线程的利用率有限                             ---  线程利用率不高


    线程池:  解决线程创建数量有限的问题, 复用线程 (网络IO 业务逻辑解除耦合性,避免一个连接创建一个线程)            


    IO复用技术:解决大量线程阻塞线程利用率不高的弊端.


    单个Reactor 单个线程处理网络IO连接 读写操作   +  业务逻辑.    网络模型不稳定,超高并发情况下不可靠,不能及时处理客户的连接请求等弊端,接入量低


    单Reactor  +   多线程(线程池)   使用work_threads 来处理业务逻辑, 将网络IO和业务逻辑解除耦合性, 提高服务器面对高并发时候的稳定性, 可靠性, 但是对于突然的超多接入量情况下还是存在缺陷,因为Reactor 既处理acceptor  还处理 IO read write。而且也没有充分利用起来多核CPU的优势


    多Reactor  +  线程池  模型,mainReactor仅仅只是处理 acceptor 连接,   subReactor来处理 IO read write 操作.    大大提高了接入量  +  大大提高服务器的稳定新  和 可靠性,各个模块之间低耦合 且职责单一,更符合设计模式的要求


    相关文章
    |
    2月前
    |
    存储 NoSQL Redis
    Redis 新版本引入多线程的利弊分析
    【10月更文挑战第16天】Redis 新版本引入多线程是一个具有挑战性和机遇的改变。虽然多线程带来了一些潜在的问题和挑战,但也为 Redis 提供了进一步提升性能和扩展能力的可能性。在实际应用中,我们需要根据具体的需求和场景,综合评估多线程的利弊,谨慎地选择和使用 Redis 的新版本。同时,Redis 开发者也需要不断努力,优化和完善多线程机制,以提供更加稳定、高效和可靠的 Redis 服务。
    48 1
    |
    2月前
    线程CPU异常定位分析
    【10月更文挑战第3天】 开发过程中会出现一些CPU异常升高的问题,想要定位到具体的位置就需要一系列的分析,记录一些分析手段。
    67 0
    |
    4月前
    |
    存储 监控 Java
    Java多线程优化:提高线程池性能的技巧与实践
    Java多线程优化:提高线程池性能的技巧与实践
    123 1
    |
    4月前
    |
    编解码 网络协议 API
    Netty运行原理问题之Netty的主次Reactor多线程模型工作的问题如何解决
    Netty运行原理问题之Netty的主次Reactor多线程模型工作的问题如何解决
    |
    3月前
    |
    缓存 Java 应用服务中间件
    Java虚拟线程探究与性能解析
    本文主要介绍了阿里云在Java-虚拟-线程任务中的新进展和技术细节。
    110 23
    |
    2月前
    |
    NoSQL Java Redis
    Reactor实战,创建一个简单的单线程Reactor(理解了就相当于理解了多线程的Reactor)
    本文通过一个简单的单线程Reactor模式的Java代码示例,展示了如何使用NIO创建一个服务端,处理客户端的连接和数据读写,帮助理解Reactor模式的核心原理。
    33 0
    Reactor实战,创建一个简单的单线程Reactor(理解了就相当于理解了多线程的Reactor)
    |
    3月前
    |
    并行计算 API 调度
    探索Python中的并发编程:线程与进程的对比分析
    【9月更文挑战第21天】本文深入探讨了Python中并发编程的核心概念,通过直观的代码示例和清晰的逻辑推理,引导读者理解线程与进程在解决并发问题时的不同应用场景。我们将从基础理论出发,逐步过渡到实际案例分析,旨在揭示Python并发模型的内在机制,并比较它们在执行效率、资源占用和适用场景方面的差异。文章不仅适合初学者构建并发编程的基础认识,同时也为有经验的开发者提供深度思考的视角。
    |
    4月前
    |
    存储 监控 Java
    |
    4月前
    |
    安全 Java 开发者
    Swing 的线程安全分析
    【8月更文挑战第22天】
    63 4
    |
    4月前
    |
    Java 数据库连接 数据库
    当线程中发生异常时的情况分析
    【8月更文挑战第22天】
    113 4