服务器框架设计模式|多线程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模型
服务器框架设计模式|多线程Reactor分析,从性能,客户接入量方向
文章图片

  • 缺点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事件处理--- 单个线程中实现
服务器框架设计模式|多线程Reactor分析,从性能,客户接入量方向
文章图片

缺陷:
  1. 单个线程处理所有请求, 对于多核CPU着实是一种浪费
  2. 当处理读写任务的线程负载过高后,处理速度下降,事件会堆积,严重的会超时,可能导致客户端重新发送请求,性能越来越差
  3. 不能支持高接入量,服务器的接入量低,因为在 accept 建立连接的请求中夹杂了大量的业务处理,业务处理耗时长, 造成accept占比低下,能同时支持的用户接入量低下
典型代表实例:redis 内存数据库 操作redis当中的数据结构
  • 单Reactor多线程模型
和单Reactor单线程相比核心在于将业务逻辑从Reactor中剥离出来放入work_threads中进行处理,实现网络IO和 业务处理之间的解耦合。 充分利用多核资源,提高性能, 提高了用户接入量和可靠性
服务器框架设计模式|多线程Reactor分析,从性能,客户接入量方向
文章图片

缺陷:
Reactor线程承担所有的事件,既要处理新连接的建立,又要处理read, send IO事件, 高并发场景下单线程存在性能问题,并且对于高接入量场景下无法及时响应大量的acceptor.
代表:skynet
  • 多Reactor多线程模型
这种模型下和第二种模型相比是把Reactor线程拆分了mainReactor和subReactor两个部分,mainReactor只处理连接事件,读写事件交给subReactor来处理。业务逻辑还是由线程池来处理.
服务器框架设计模式|多线程Reactor分析,从性能,客户接入量方向
文章图片

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


【服务器框架设计模式|多线程Reactor分析,从性能,客户接入量方向】

    推荐阅读