Socket Server 的 N 种并发模型汇总

2020-04-06 10:06:08 +08:00
 sanbenweiyang

原创声明 作者: 刘丹冰 Aceld,微信公众号同名

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

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


模型一、单线程 Accept (无 IO 复用)

(1) 模型结构图

(2) 模型分析

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

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

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

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

(3) 优缺点

优点

缺点


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

(1) 模型结构图

(2) 模型分析

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

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

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

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

(3) 优缺点

优点

缺点

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


模型三、单线程多路 IO 复用

(1) 模型结构图

(2) 模型分析

① 主线程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 复用机制阻塞,其他链接过来重复 ②、③流程。

(3) 优缺点

优点

缺点


模型四、单线程多路 IO 复用+多线程读写业务(业务工作池)

(1) 模型结构图

(2) 模型分析

① 主线程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写给对方。

(3) 优缺点

优点

缺点


模型五、单线程 IO 复用+多线程 IO 复用(链接线程池)

(1) 模型结构图

(2) 模型分析

① 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有读写事件,对应的线程处理该套接字的读写及业务。

(3) 优缺点

优点

缺点


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

(1) 模型结构图

(2) 模型分析

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

不同处

(3) 优缺点

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

不同处:

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

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


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

(1) 模型结构图

(2) 模型分析

① 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重新加回线程池的监控线程中,同时自身线程自我销毁。

(3) 优缺点

优点

缺点


总结

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

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


###关于作者:

mail: danbing.at@gmail.com github: https://github.com/aceld 原创书籍 gitbook: http://legacy.gitbook.com/@aceld

创作不易, 共同学习进步, 欢迎关注作者, 回复"zinx"有好礼


文章推荐

开源软件作品

(原创开源)Zinx-基于 Golang 轻量级服务器并发框架-完整版(附教程视频)

(原创开源)Lars-基于 C++负载均衡远程调度系统-完整版

精选文章

典藏版-Golang 调度器 GMP 原理与调度全分析

典藏版-Golang 三色标记、混合写屏障 GC 模式图文全分析

最常用的调试 golang 的 bug 以及性能问题的实践方法?

Golang 中的 Defer 必掌握的 7 知识点

Golang 中的局部变量“何时栈?何时堆?”

使用 Golang 的 interface 接口设计原则

流? I/O 操作?阻塞? epoll?

深入浅出 Golang 的协程池设计

Go 语言构建微服务一站式解决方案


1481 次点击
所在节点    程序员
3 条回复
hhhsuan
2020-04-06 10:50:47 +08:00
看不到图?
paoqi2048
2020-04-06 20:23:26 +08:00
两个模型五
Meltdown
2020-04-07 00:24:33 +08:00
默认 tcp 么,UDP 怎么多线程呢…

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/659754

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX