主要介绍服务器模型,服务器-客户端模型架构以及几种高效的时间处理模式,几种高效的并发模式以及一种程序的设计思想(也就是状态机的思想)
- 服务器的两种基本架构:
C/S
架构,P2P
架构,这里主要讨论C/S
架构 - 服务器编程框架,基本架构如下:
IO
处理单元 -> 逻辑单元(比如工作进程和线程等) -> 网络存储单元(可选)(比如数据库等),基本架构如下: - 下面介绍几种
IO
模式,大体分为 同步模式和异步模式,这两种模式的区别就是:- 同步模式: 把自己想象为客户端,利用同步的
IO
处理模式得到的时间就是读就绪或和写就绪时间,具体的读写操作需要自己执行(可以理解为顺序执行) - 异步模式: 利用异步的
IO
处理模式得到的是IO
完成时间,实际的IO
读写事件其实发生在后端/kernel
中
- 同步模式: 把自己想象为客户端,利用同步的
- 下面介绍几种基于同步或者异步模式的
IO
函数:- 同步模式:
- 阻塞
IO
,比如不设置IO
属性的网络套接字操作 IO
多路复用: 比如select
,poll
,epoll
- 信号驱动
IO
, 也就是某一个文件的某一个事件通过触发信号的方式来调用信号处理函数从而完成IO
操作
- 阻塞
- 异步模式:
- 异步的
IO
模式当监听到读就绪或者写就绪的时候自己在内核中完成读写操作,比如Linux
中的aio_read
等函数
- 异步的
- 同步模式:
- 两种高效的事件处理模式(比如读事件,写事件等):
reactor
: 一般用于同步模式: 这一种模式下,主进程的作用就是不断监听事件,并且把事件放入到请求队列中,之后子进程通过来处理事件并且同时把写事件页注册到IO
多路复用函数中proactor
: 一般用于异步模式: 这一种模式下,所有的读写操作都是由内核来完成,内核完成读写操作之后通过发送信号从而触发信号处理函数从而选择工作进程执行善后工作,工作进程也可以调用异步的IO
函数让内核执行相应的操作- 模拟
proactor
模式: 利用同步的方式来模拟proactor
,其实就是主进程代替了内核的功能,也就是代替内核完成读写的操作 三种模式的基本架构如下(这里的IO
多路复用函数使用epoll
):
- 接下来介绍两种高效的并发模式:
- 半同步/半异步模式: 这里的同步是指程序中的代码是顺序执行的,异步是指的程序中的代码不是顺序执行的(比如信号的处理函数等)
- 领导者/追随者模式: 领导者负责监听的功能,当监听到事件就会处理事件从而转到
processing
模式,领导者可以互换
- 半同步/半异步模式: 同步进程进行客户逻辑的处理,异步进程进行事件的监听,同时为了拓展监听的事件的数量可以使用半同步/半异步反应堆模式,整体的架构如下(感觉类似于
reactor
,但是reactor
侧重于事件,这里侧重于执行工作的线程和进程等资源) - 领导者追随者模式,明确几种组件: 句柄类,事件处理器,具体的事件处理器和线程集等,注意数据交换方式,下面为系统架构以及时序逻辑图:
- 状态机: 当程序的状态进程发生转换的时候就可以使用状态机法来描述程序(比如可靠数据传递的实现(
TCP
))的实现,一般难以用到 - 优化服务器的几种策略:
- 池化技术: 线程池,进程池等
- 计算密集型 -> 单线程,
IO
密集型 -> 多线程(但是需要考虑上下文切换和锁) - 数据复制使用零拷贝(直接由内核进行拷贝即可)