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

目录

前言

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

并发编程的最初模型 --- 多线程阻塞IO模型

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

二.Reactor线程模型分类

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

单Reactor单线程模型

单Reactor多线程模型

多Reactor多线程模型

三.Reactor线程模型生活化

四. 总结本章


前言

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

epoll高度封装reactor,几乎所有可见服务器的底层框架_小杰312的博客-CSDN博客epoll高度封装reactor,几乎所有可见服务器的底层框架https://blog.csdn.net/weixin_53695360/article/details/123894158?spm=1001.2014.3001.5502

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

  • 并发编程的最初模型 --- 多线程阻塞IO模型

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p2wMzEy,size_20,color_FFFFFF,t_70,g_se,x_16

  • 缺点1:   每一个connect 都对应一个线程,线程占用系统资源,并发数过大时,系统资源不足以支撑.      (系统资源上限制并发量)
  • 缺点2:    阻塞IO,在等待IO到来的时候会阻塞住线程,阻塞占用线程, 线程利用率低下,且线程数量有限,是对资源的一种极大的浪费   (占着线程不工作)

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

  1. 基于池化思想,避免为每个连接创建线程,连接完成后将业务处理交给线程池处理. (开启work_threads线程池处理业务需求)     ---  实现网络IO  跟   业务处理的解耦合 同时避免为每一个连接创建线程
  2. 基于IO复用技术,多个连接阻塞在同一个对象上,多个连接中出现IO事件的触发,操作系统就会通知应用程序处理                       ---  还是阻塞, 但是是多个IO阻塞在一个对象上,  所以多路:就是多个IO,复用 :复用一个线程
  • 理解IO复用:对比一下普通阻塞IO: 一个IO事件单独阻塞一个线程,     多路IO复用: 多个IO事件共同阻塞一个线程                            ---   将多个IO阻塞等待 重合阻塞在一起。提高线程利用率.

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

二.Reactor线程模型分类

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

  • 单Reactor单线程模型

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

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p2wMzEy,size_20,color_FFFFFF,t_70,g_se,x_16

缺陷:

  1. 单个线程处理所有请求, 对于多核CPU着实是一种浪费
  2. 当处理读写任务的线程负载过高后,处理速度下降,事件会堆积,严重的会超时,可能导致客户端重新发送请求,性能越来越差     
  3. 不能支持高接入量,  服务器的接入量低,  因为在 accept 建立连接的请求中夹杂了大量的业务处理,业务处理耗时长, 造成accept占比低下,能同时支持的用户接入量低下

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

  • 单Reactor多线程模型

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

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p2wMzEy,size_20,color_FFFFFF,t_70,g_se,x_16

缺陷:

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

代表:skynet

  • 多Reactor多线程模型

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

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p2wMzEy,size_20,color_FFFFFF,t_70,g_se,x_16

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

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

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

三.Reactor线程模型生活化

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

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

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

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

  3. 多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 操作.    大大提高了接入量  +  大大提高服务器的稳定新  和 可靠性,各个模块之间低耦合 且职责单一,更符合设计模式的要求

  • 63
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 96
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 96
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小杰312

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值