热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:SocketServer的N种并发模型汇总

篇首语:本文由编程笔记#小编为大家整理,主要介绍了SocketServer的N种并发模型汇总相关的知识,希望对你有一定的参考价值。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了Socket Server的N种并发模型汇总相关的知识,希望对你有一定的参考价值。










      本文主要介绍常见的Server的并发模型,这些模型与编程语言本身无关,有的编程语言可能在语法上直接透明了模型本质,所以开发者没必要一定要基于模型去编写,只是需要知道和了解并发模型的构成和特点即可。









    在了解并发模型之前,我们需要两个必备的前置知识



  • socket网络编程


  • 多路IO复用机制


  • 多线程/多进程等并发编程理论














提纲
























模型一


单线程Accept(无I/O复用)














模型二


单线程Accept+多线程读写业务(无I/O复用)














模型三


单线程多路I/O复用
















模型四


单线程多路I/O复用+多线程读写业务(业务工作池)














模型五


单线程多路I/O复用+多线程多路I/O复用(线程池)














模型五(进程版)


单进程多路I/O复用+多进程多路I/O复用(进程池)
















模型六


单线程多路I/O复用+多线程多路I/O复用+多线程
































模型一、单线程Accept(无I/O复用)




















01












模型结构图























02












模型分析














① 主线程
main thread执行阻塞Accept,每次客户端Connect链接过来,
main thread中accept响应并建立连接




② 创建链接成功,得到
Connfd1套接字后, 依然在
main thread串行处理套接字读写,并处理业务。


③ 在②处理业务中,如果有新客户端
Connect过来,
Server无响应,直到当前套接字全部业务处理完毕。


④ 当前客户端处理完后,完毕链接,处理下一个客户端请求。












03












优缺点















优点


  • socket编程流程清晰且简单,适合学习使用,了解socket基本编程流程。




缺点


  • 该模型并非并发模型,是串行的服务器,同一时刻,监听并响应最大的网络请求量为1。即并发量为1


  • 仅适合学习基本socket编程,不适合任何服务器Server构建。


















模型二、单线程Accept+多线程读写业务(无I/O复用)




















01












模型结构图












Socket Server的N种并发模型汇总










02












模型分析














① 主线程
main thread执行阻塞Accept,每次客户端Connect链接过来,
main thread中accept响应并建立连接




② 创建链接成功,得到
Connfd1套接字后,创建一个新线程
thread1用来处理客户端的读写业务。
main thead依然回到
Accept阻塞等待新客户端。


③ 
thread1通过套接字
Connfd1与客户端进行通信读写。


④ server在②处理业务中,如果有新客户端
Connect过来,
main thread
Accept依然响应并建立连接,重复②过程。








03












优缺点














优点


  • 基于模型一:单线程Accept(无IO复用) 支持了并发的特性。


  • 使用灵活,一个客户端对应一个线程单独处理,server处理业务内聚程度高,客户端无论如何写,服务端均会有一个线程做资源响应。




缺点


  • 随着客户端的数量增多,需要开辟的线程也增加,客户端与server线程数量1:1正比关系,一次对于高并发场景,线程数量到硬件上限瓶颈。


  • 对于长链接,客户端一旦无业务读写,只要不关闭,server的对应线程依然需要保持连接(心跳、健康监测等机制),占用连接资源和线程开销资源浪费。


  • 仅适合客户端数量不大,并且数量可控的场景使用。




仅适合学习基本socket编程,不适合任何服务器Server构建。


















模型三、单线程多路I/O复用




















01












模型结构图












Socket Server的N种并发模型汇总









02












模型分析














① 主线程
main thread创建
listenFd之后,采用多路I/O复用机制(如:select、epoll)进行IO状态阻塞监控。有
Client1客户端
Connect请求,I/O复用机制检测到
ListenFd触发读事件,则进行
Accept建立连接,并将新生成的
connFd1加入到
监听I/O集合中。


② 
Client1再次进行正常读写业务请求,
main thread
多路I/O复用机制阻塞返回,会触该套接字的读/写事件等。


③ 对于
Client1的读写业务,Server依然在
main thread执行流程继续执行,此时如果有新的客户端
Connect链接请求过来,Server将没有即时响应。


④ 等到Server处理完一个连接的
Read+Write操作,继续回到
多路I/O复用机制阻塞,其他链接过来重复 ②、③流程。








03












优缺点














优点




  • 单流程解决了可以同时监听多个客户端读写状态的模型,不需要1:1与客户端的线程数量关系。


  • 多路I/O复用阻塞,非忙轮询状态,不浪费CPU资源, CPU利用率较高。




缺点


  • 虽然可以监听多个客户端的读写状态,但是同一时间内,只能处理一个客户端的读写操作,实际上读写的业务并发为1。


  • 多客户端访问Server,业务为串行执行,大量请求会有排队延迟现象,如图中⑤所示,当Client3占据main thread流程时,Client1,Client2流程卡在IO复用等待下次监听触发事件。


















模型四、单线程多路I/O复用+多线程读写业务


(业务工作池)





















01












模型结构图












Socket Server的N种并发模型汇总









02












模型分析














① 主线程
main thread创建
listenFd之后,采用多路I/O复用机制(如:select、epoll)进行IO状态阻塞监控。有
Client1客户端
Connect请求,I/O复用机制检测到
ListenFd触发读事件,则进行
Accept建立连接,并将新生成的
connFd1加入到
监听I/O集合中。


② 当
connFd1有可读消息,触发读事件,并且进行读写消息


③ 
main thread按照固定的协议读取消息,并且交给
worker pool工作线程池, 工作线程池在server启动之前就已经开启固定数量的
thread,里面的线程只处理消息业务,不进行套接字读写操作。


④ 工作池处理完业务,触发
connFd1写事件,将回执客户端的消息通过
main thead写给对方。








03












优缺点














优点


  • 对于模型三, 将业务处理部分,通过工作池分离出来,减少多客户端访问Server,业务为串行执行,大量请求会有排队延迟时间。


  • 实际上读写的业务并发为1,但是业务流程并发为worker pool线程数量,加快了业务处理并行效率。




缺点


  • 读写依然为main thread单独处理,最高读写并行通道依然为1.


  • 虽然多个worker线程处理业务,但是最后返回给客户端,依旧需要排队,因为出口还是main threadRead + Write


















模型五、单线程I/O复用+多线程I/O复用


(线程池)





















01












模型结构图








Socket Server的N种并发模型汇总









02












模型分析














① Server在启动监听之前,开辟固定数量(N)的线程,用
Thead Pool线程池管理


② 主线程
main thread创建
listenFd之后,采用多路I/O复用机制(如:select、epoll)进行IO状态阻塞监控。有
Client1客户端
Connect请求,I/O复用机制检测到
ListenFd触发读事件,则进行
Accept建立连接,并将新生成的
connFd1分发给
Thread Pool中的某个线程进行监听。


③ 
Thread Pool中的每个
thread都启动
多路I/O复用机制(select、epoll),用来监听
main thread建立成功并且分发下来的socket套接字。


④ 如图, 
thread监听
ConnFd1、ConnFd2
thread2监听
ConnFd3,
thread3监听
ConnFd4. 当对应的
ConnFd有读写事件,对应的线程处理该套接字的读写及业务。








03












优缺点














优点


  • main thread的单流程读写,分散到多线程完成,这样增加了同一时刻的读写并行通道,并行通道数量N, N为线程池Thread数量。


  • server同时监听的ConnFd套接字数量几乎成倍增大,之前的全部监控数量取决于main thread多路I/O复用机制的最大限制(select 默认为1024, epoll默认与内存大小相关,约3~6w不等),所以理论单点Server最高响应并发数量为N*(3~6W)(N为线程池Thread数量,建议与CPU核心成比例1:1)。


  • 如果良好的线程池数量和CPU核心数适配,那么可以尝试CPU核心与Thread进行绑定,从而降低CPU的切换频率,提升每个Thread处理合理业务的效率,降低CPU切换成本开销。




缺点


  • 虽然监听的并发数量提升,但是最高读写并行通道依然为N,而且多个身处同一个Thread的客户端,会出现读写延迟现象,实际上每个Thread的模型特征与模型三:单线程多路IO复用一致。


















模型五(进程版)、单进程多路I/O复用+多进程多路I/O复用


(进程池)






















01












模型结构图












Socket Server的N种并发模型汇总









02












模型分析















五、单线程IO复用+多线程IO复用(链接线程池)无大差异。


不同处


  • 进程和线程的内存布局不同导致,main process(主进程)不再进行Accept操作,而是将Accept过程分散到各个子进程(process)中.


  • 进程的特性,资源独立,所以main process如果Accept成功的fd,其他进程无法共享资源,所以需要各子进程自行Accept创建链接


  • main process只是监听ListenFd状态,一旦触发读事件(有新连接请求). 通过一些IPC(进程间通信:如信号、共享内存、管道)等, 让各自子进程Process竞争Accept完成链接建立,并各自监听。










03












优缺点















五、单线程IO复用+多线程IO复用(链接线程池)无大差异。


不同处:


多进程内存资源空间占用稍微大一些


多进程模型安全稳定
较强,这也是因为各自进程互不干扰的特点导致。
















模型六、单线程多路I/O复用+多线程多路I/O复用+多线程




















01












模型结构图














Socket Server的N种并发模型汇总









02












模型分析














① Server在启动监听之前,开辟固定数量(N)的线程,用
Thead Pool线程池管理


② 主线程
main thread创建
listenFd之后,采用多路I/O复用机制(如:select、epoll)进行IO状态阻塞监控。有
Client1客户端
Connect请求,I/O复用机制检测到
ListenFd触发读事件,则进行
Accept建立连接,并将新生成的
connFd1分发给
Thread Pool中的某个线程进行监听。


③ 
Thread Pool中的每个
thread都启动
多路I/O复用机制(select、epoll),用来监听
main thread建立成功并且分发下来的socket套接字。一旦其中某个被监听的客户端套接字触发
I/O读写事件,那么,会立刻开辟一个新线程来处理
I/O读写业务。


④ 但某个读写线程完成当前读写业务,如果当前套接字没有被关闭,那么将当前客户端套接字
如:ConnFd3重新加回线程池的监控线程中,同时自身线程自我销毁。








03












优缺点














优点


  • 模型五、单线程IO复用+多线程IO复用(链接线程池)基础上,除了能够保证同时响应的最高并发数,又能解决读写并行通道局限的问题。


  • 同一时刻的读写并行通道,达到最大化极限,一个客户端可以对应一个单独执行流程处理读写业务,读写并行通道与客户端数量1:1关系。




缺点


  • 该模型过于理想化,因为要求CPU核心数量足够大。


  • 如果硬件CPU数量可数(目前的硬件情况),那么该模型将造成大量的CPU切换成本浪费。因为为了保证读写并行通道与客户端1:1的关系,那么Server需要开辟的Thread数量就与客户端一致,那么线程池中做多路I/O复用的监听线程池绑定CPU数量将变得毫无意义。


  • 如果每个临时的读写Thread都能够绑定一个单独的CPU,那么此模型将是最优模型。但是目前CPU的数量无法与客户端的数量达到一个量级,目前甚至差的不是几个量级的事。

















总结














        综上,我们整理了7中Server的服务器处理结构模型,每个模型都有各自的特点和优势,那么对于多少应付高并发和高CPU利用率的模型,
目前多数采用的是模型五(或模型五进程版,如Nginx就是类似模型五进程版的改版)。


        
至于并发模型并非设计的复杂越好,也不是线程开辟的越多越好,
我们要考虑硬件的利用与和切换成本的开销。
“模型六”
设计就极为复杂,线程较多,但以当今的硬件能力无法支撑,反倒导致该模型性能极差。所以
对于不同的业务场景也要选择适合的模型构建
,并不是一定固定就要使用某个来应用。

















end













































推荐阅读










喜欢本文的朋友,欢迎关注“Go语言中文网











推荐阅读
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
  • 基于事件驱动的并发编程及其消息通信机制的同步与异步、阻塞与非阻塞、IO模型的分类
    本文介绍了基于事件驱动的并发编程中的消息通信机制,包括同步和异步的概念及其区别,阻塞和非阻塞的状态,以及IO模型的分类。同步阻塞IO、同步非阻塞IO、异步阻塞IO和异步非阻塞IO等不同的IO模型被详细解释。这些概念和模型对于理解并发编程中的消息通信和IO操作具有重要意义。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • Google在I/O开发者大会详细介绍Android N系统的更新和安全性提升
    Google在2016年的I/O开发者大会上详细介绍了Android N系统的更新和安全性提升。Android N系统在安全方面支持无缝升级更新和修补漏洞,引入了基于文件的数据加密系统和移动版本的Chrome浏览器可以识别恶意网站等新的安全机制。在性能方面,Android N内置了先进的图形处理系统Vulkan,加入了JIT编译器以提高安装效率和减少应用程序的占用空间。此外,Android N还具有自动关闭长时间未使用的后台应用程序来释放系统资源的机制。 ... [详细]
  • 浏览器中的异常检测算法及其在深度学习中的应用
    本文介绍了在浏览器中进行异常检测的算法,包括统计学方法和机器学习方法,并探讨了异常检测在深度学习中的应用。异常检测在金融领域的信用卡欺诈、企业安全领域的非法入侵、IT运维中的设备维护时间点预测等方面具有广泛的应用。通过使用TensorFlow.js进行异常检测,可以实现对单变量和多变量异常的检测。统计学方法通过估计数据的分布概率来计算数据点的异常概率,而机器学习方法则通过训练数据来建立异常检测模型。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
  • Java 11相对于Java 8,OptaPlanner性能提升有多大?
    本文通过基准测试比较了Java 11和Java 8对OptaPlanner的性能提升。测试结果表明,在相同的硬件环境下,Java 11相对于Java 8在垃圾回收方面表现更好,从而提升了OptaPlanner的性能。 ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有